目的
Ubuntuで本番稼働を想定したASP.NET coreアプリケーションの実行環境を構築する。
参考
Nginx搭載のlINUXでASP.NET Coreをホストする
本題
アプリケーションの作成と、動作確認
アプリケーションの中身にはこだわらないので、テンプレートで作成したものをPublishしていく。
実行コマンド。
> mkdir helloworld
> cd helloworld/
> dotnet new webapi
> dotnet run
ここまでで、アプリの作成と起動ができた。https://localhost:5001/swagger/index.htmlにアクセスし、動作を確認する。Swaggerの画面が開けば、OK。
デプロイ対象のDLLの作成とデプロイ
前のステップで作成、実行されたDLLは、Debug用のDLLとなる。そのため、Release用のDLLの作成は別途行う。このとき、一般的にwEBアプリが配置されるとされるディレクトリ(/var/www/)配下に、アプリケーション用のディレクトリhelloworldを作成する。dotnet publishコマンド実行時には、作成下ディレクトリ配下に出力されるように-oオプションを設定する。
> sudo mkdir -p /var/www/helloworld
> sudo dotnet publish -o /var/www/helloworld
出来上がったファイルたちの確認。
> ls /var/www/helloworld
total 3792 -rw-rw-r-- 1 root root 162 4月 24 17:34 appsettings.Development.json -rw-rw-r-- 1 root root 192 4月 24 17:34 appsettings.json -rwxr-xr-x 1 root root 138528 4月 24 17:59 helloworld -rw-rw-r-- 1 root root 107626 4月 24 17:59 helloworld.deps.json -rw-rw-r-- 1 root root 10752 4月 24 17:59 helloworld.dll -rw-rw-r-- 1 root root 20380 4月 24 17:59 helloworld.pdb -rw-rw-r-- 1 root root 292 4月 24 17:59 helloworld.runtimeconfig.json -rwxr--r-- 1 root root 173960 8月 29 2020 Microsoft.OpenApi.dll -rwxr--r-- 1 root root 15872 9月 23 2020 Swashbuckle.AspNetCore.Swagger.dll -rwxr--r-- 1 root root 80384 9月 23 2020 Swashbuckle.AspNetCore.SwaggerGen.dll -rwxr--r-- 1 root root 3308544 9月 23 2020 Swashbuckle.AspNetCore.SwaggerUI.dll -rw-r--r-- 1 root root 486 4月 24 17:59 web.config
アプリを実行し、Swaggerにアクセスしてみる。
> cd /var/www/helloworld
> dotnet run
・・・が、https://localhost:5001/swagger/index.htmlにアクセスしても表示されない。生成されたアプリのStartup.csを見てみると、Swaggerが利用されるのは、実行環境がDevelopmentのときだけになっていた。SwaggerのオプションをIf文のスコープから外し、Releaseモードのときも利用できるようにしたら期待通りの動作になった。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "KestrelSample v1")); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
サービスの起動
前のステップでは、DOTNETコマンドを利用してkestrelプロセスを起動した。次は、SYSTEMDを利用し、サービスとしてHelloworldアプリを登録し、SYSTEMDによって、サービスの起動・停止・監視を行うように設定を進める。
参考)
- なぜsystemdなのか?
- DOCUMENT
サービスファイルの作成
[Unit] Description=Example .NET Web API App running on Ubuntu [Service] WorkingDirectory=/var/www/helloworld ExecStart=/usr/bin/dotnet /var/www/helloworld/helloworld.dll Restart=always # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 KillSignal=SIGINT SyslogIdentifier=dotnet-helloworld User=kinakomotitti Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target
登録と起動
以下のコマンドで、サービスを有効化&起動。
> sudo systemctl enable helloworld
> sudo systemctl start helloworld
サービスの状態を確認する。
> sudo systemctl status helloworld
● helloworld.service - Example .NET Web API App running on Ubuntu Loaded: loaded (/etc/systemd/system/helloworld.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2021-04-24 19:30:46 JST; 9s ago Main PID: 211090 (dotnet) Tasks: 20 (limit: 9113) Memory: 27.9M CGroup: /system.slice/helloworld.service └─211090 /usr/bin/dotnet /var/www/helloworld/helloworld.dll
ここまでで、アプリケーションサーバーの起動ができた。あとは、Webサーバーとしてより高機能なものを利用してアクセスできるようにする。
リバースプロキシサーバーの設定
dotnet coreでは、kestrelという規定のクロスプラットフォームHTTPサーバーがある。これを利用してWebアプリケーションを実行することは可能だが、リバースプロキシ(IIS,Nginx,Apacheなど)を利用することで、以下のメリットを享受することができる。このときの処理の流れは、
Client -> リバースプロキシ -> Kestrel -> アプリケーション本体
となる。
Nginxのインストール
Official Debian/Ubuntu packagesに従い、インストールする。
> sudo apt-get update
> sudo apt-get install nginx
> sudo systemctl status nginx
もし起動していなかったら、systemctl start nginxで起動させる。
Nginxの構成を修正する
/etc/nginx/sites-available.defaultをテキストエディターで開き、修正する。今回は、localhostに対するリクエストをkestrelに転送してほしかったため、規定で作成されたdefaultファイルを以下のとおりに変更した。
# もともとコメントアウトされていた箇所は省略。 server { listen 80 default_server; listen [::]:80 default_server; #root /var/www/html; server_name _; location / { # 追加↓ proxy_pass http://127.0.0.1:5000; # コメントアウト↓ # try_files $uri $uri/ =404; } }
sudo nginx -s reloadコマンドで上記変更を矯正適用すると、http:/localhost/swaggerでHelloworldアプリのSwaggerにアクセスすることができた。
Logの確認
Nginxのアクセスログについては、> tail -f /var/log/nginx/access.log
で確認することができる。
Kestrelで実行されているHelloworldアプリの標準出力は、> sudo journalctl -fu hellowold
で確認することができる。ただし、いまはログ出力の処理を実装していないため、何も表示されない。