.NET Core ASP.NET Core Blazor CentOS Nginx Visual Studio

Blazor Server をデプロイしてみた

.NET Core

ASP.NET Core Blazor Server のホストとデプロイ

とにかく .Net Core(Blazor) が Linux で動作することを確認したかった

環境

開発環境

  • Windows 10
  • Microsoft Visual Studio Community 2019 Version 16.4.4
  • Blazor アプリケーション

公開サーバー( Nginx で ASP.NET Core 公開済みのVPS)

  • VPS WebARENA Indigo
  • CPU 2vCPU
  • SSD 40GB
  • メモリ 2GB
  • 月額699円(税込)1時間当たり1.1円(税込)初期料金無料
  • CentOS Linux release 7.7.1908 (Core)
  • Nginx version: Nginx/1.17.8

公開までの手順

Blazor サーバーサイドアプリケーションの作成 PC作業

なにはさておき デプロイとホストをしてみたかった
Visual Studio 起動 「新しいプロジェクトの作成」


「Blazor アプリ」選択

「プロジェクト名」と保存フォルダーを入力して「作成」

「Blazor サーバーアプリ」「作成」

出来上がった開発画面

「F5 デバッグの開始」でビルド成功してアプリケーション起動した画面

デプロイ PC作業

左側ペインに「公開」があればこれか、上部メニュー「ビルド」「BlazorApp1 の発行」

「開始」

左側ペイン「フォルダ」パブリッシュするローカルPCのフォルダを指定
左側ペインの公開先について

  • App Service:Azure のアプリケーションサービス 仮想マシンは準備不要だが課金が高そうだった
  • Azure Virtual Machines : Azure 状に自分で用意した仮想マシン .net core なのでクロスプラットフォーム対応かと思う。未経験
  • IIS、FTP、その他 : 未経験
  • フォルダー : 一時的な仮置き場 直接公開サーバーのフォルダーでも良いのかも?


「発行」

発行結果

WinSCP で CentOS 公開サーバーへコピー

補足 ポートについて

後で気づいたのだが
Visual Studio でWebサーバーに 「IIS Express」を選択すると http:50687 https:44357 になる様だ。

「BlazorApp1」を選択したら 今までの ASP.NET Core と同じく http:5000 https:5001 になった。
最終的にこちらでビルドしてからデプロイした
IIS Express でビルド後デプロイしても問題ないのか今のところ不明。
jsonファイル等には 5000ポート等の記載は無かった様なので関係ないのかも?

Nginxリバースプロシキーの設定 Linux作業

手動で Blazor サーバーアプリケーションの .dll を起動してみた

以前配置済みの ASP.NET Core アプリケーション用監視デーモン
/etc/systemd/system/kestrel-netcore-web.service が動いていると次のようなエラーで失敗しました。

[root@i- blazorapp1]# dotnet ./BlazorApp1.dll
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.IO.IOException: Failed to bind to address http://127.0.0.1:5000: address already in use.

対策 このデーモンを停止

[root@i- system]# systemctl stop kestrel-netcore-web.service

対策 この asp.net core アプリケーション監視デーモンの自動起動の解除

[root@i- system]# systemctl disable kestrel-netcore-web.service
Removed symlink /etc/systemd/system/multi-user.target.wants/kestrel-netcore-web.service.

Blazor アプリケーションを手動起動 成功

[root@i- system]# /usr/bin/dotnet /var/www/blazorapp1/BlazorApp1.dll
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /var/www/blazorapp1

既存の Nginx リバースプロシキー構成ファイルを Blazor 用に変更

以前作成済みの ASP.NET Core 用構成ファイルを変更して使ってみる

[root@i- conf.d]# cat /etc/nginx/conf.d/netcore2-nginx.conf
server {
    server_name   yyy.domain *.yyy.domain;;
    location / {
#        proxy_pass         http://localhost:44357;
        proxy_pass         http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;    ←
#        proxy_set_header   Connection keep-alive;
        proxy_set_header   Connection $connection_upgrade; ←
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/yyy.domain/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/yyy.domain/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = yyy.domain) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen  80;
    server_name   yyy.domain *.yyy.domain;
    return 404; # managed by Certbot


}

BlazorApp1.dll が手動起動状態なので ブラウザからアクセスしてみる

ttp://yyy.domain
ttps://yyy.domain

結果、駄目だった。エラーログ確認

[root@i- nginx]# cat error.log
2020/02/08 16:30:29 [emerg] 16482#16482: unknown "connection_upgrade" variable

下記のように参考ページに従って編集したのだが下の設定でエラーっぽい

proxy_set_header Connection $connection_upgrade;


最終的な Nginx リバースプロシキー構成ファイルの内容

[root@i- conf.d]# cat /etc/nginx/conf.d/netcore2-nginx.conf
server {
    server_name   yyy.domain *.yyy.domain;
    location / {
#        proxy_pass         http://localhost:44357;
        proxy_pass         http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
#        proxy_set_header   Connection keep-alive;
        proxy_set_header   Connection "Upgrade";  ← この様に変更
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/yyy.domain/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/yyy.domain/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = yyy.domain) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen  80;
    server_name   yyy.domain *.yyy.domain;
    return 404; # managed by Certbot


}

 Blazor アプリケーション用監視デーモンの作成

[root@i- system]# cat /etc/systemd/system/kestrel-blazor-web.service
[Unit]
Description=Example .NET Web API App running on CentOS 7

[Service]
WorkingDirectory=/var/www/blazorapp1
ExecStart=/usr/bin/dotnet /var/www/blazorapp1/BlazorApp1.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target

デーモン自動起動の設定

[root@i- system]# cd /etc/systemd/system
[root@i- system]# systemctl enable kestrel-blazor-web.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kestrel-blazor-web.service to /etc/systemd/system/kestrel-blazor-web.service.

デーモン起動

[root@i- system]# systemctl start kestrel-blazor-web.service

動作確認

[root@i- system]# systemctl status -l kestrel-blazor-web.service
● kestrel-blazor-web.service - Example .NET Web API App running on CentOS 7
   Loaded: loaded (/etc/systemd/system/kestrel-blazor-web.service; enabled; vendor preset: disabled)
   Active: active (running) since 土 2020-02-08 21:28:11 JST; 26s ago
 Main PID: 16971 (dotnet)
   CGroup: /system.slice/kestrel-blazor-web.service
           mq16971 /usr/bin/dotnet /var/www/blazorapp1/BlazorApp1.dll

 2月 08 21:28:11 i- dotnet-example[16971]: warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
 2月 08 21:28:11 i- dotnet-example[16971]: No XML encryptor configured. Key {} may be persisted to storage in unencrypted form.
 2月 08 21:28:11 i- dotnet-example[16971]: info: Microsoft.Hosting.Lifetime[0]
 2月 08 21:28:11 i- dotnet-example[16971]: Now listening on: http://localhost:5000
 2月 08 21:28:11 i- dotnet-example[16971]: info: Microsoft.Hosting.Lifetime[0]
 2月 08 21:28:11 i- dotnet-example[16971]: Application started. Press Ctrl+C to shut down.
 2月 08 21:28:11 i- dotnet-example[16971]: info: Microsoft.Hosting.Lifetime[0]
 2月 08 21:28:11 i- dotnet-example[16971]: Hosting environment: Production
 2月 08 21:28:11 i- dotnet-example[16971]: info: Microsoft.Hosting.Lifetime[0]
 2月 08 21:28:11 i- dotnet-example[16971]: Content root path: /var/www/blazorapp1

ブラウザからアクセスしてOK!

ttp://yyy.domain
ttps://yyy.domain

まとめ

  • Visual Studio のWebサーバー指定がデフォルトの 「IIS Express」の場合ポートが5000から変化に注意
  • Nginx の場合 ブラウザーとの通信に SignalR Websocket が使われる apacheの場合は?
  • Blazor WebAssembly は今年5月GAとのことだが、起動に時間が掛かる様だが、それって問題では?
  • ようやく安価な Linux VPS で ASP.NET Core が使えそうだ。ASP.NET 経験者には朗報では。

コメント