.NET Core apache ASP.NET Core AWS CentOS

ASP.NET CoreをLinuxで公開してみた Apache編

.NET Core

従来から感じてるが Windows VPS は Linux VPS より費用負担が大きい。
Linux で ASP.NET が動けばな~ と。
まずはともかく Linux で ASP.NET Core が動くことを自分で確認したかった

環境

開発環境

  • Windows 10
  • Microsoft Visual Studio Community 2019 Version 16.4.2
  • ASP.NET Core Webアプリケーション

公開サーバー

  • AWS1年間の無料枠を利用
  • 仮想マシン t2.micro で Amazon Linux 2 AMI 2.0.20191116.0 x86_64 HVM gp2
  • Apache リバースプロシキー設定

公開までの手順

ASP.NET Core Webアプリケーションの開発 PC作業

今回はLinuxで公開できることの確認が目的なのでVisual Studio のウィザードでASP.NET Core MVCアプリケーションを作成した

公開サーバーの準備 Linux作業

AWS EC2に無料枠を使って仮想マシンの作成(投稿割愛)

MSのサイトを参考に以下進める

最終的に次のサイトに来ます。

Microsoft キーとフィードを登録する

.NET をインストールする前に、次のことを行う必要があります。

  • Microsoft キーを登録する
  • 製品リポジトリを登録する
  • 必要な依存関係をインストールする
これは、コンピューターごとに 1 回実行する必要があるだけです。
[root@ip- ~]# sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
Retrieving https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
Preparing... ################################# [100%]
Updating / installing...
1:packages-microsoft-prod-1.0-1 ################################# [100%]

ASP.NET Core ランタイムをインストールする

★.NET Core SDK はインストールしないでやってみる
インストール可能な製品を更新してから、ASP.NET ランタイムをインストール

[root@ip- ~]# sudo yum install aspnetcore-runtime-3.1
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core | 2.4 kB 00:00:00
amzn2extra-docker | 1.3 kB 00:00:00
packages-microsoft-com-prod | 2.9 kB 00:00:00
packages-microsoft-com-prod/primary_db | 102 kB 00:00:00
Resolving Dependencies
--> Running transaction check

------------------------------------------------------------------------

Installed:
aspnetcore-runtime-3.1.x86_64 0:3.1.0-1

Dependency Installed:
dotnet-host.x86_64 0:3.1.0-1 dotnet-hostfxr-3.1.x86_64 0:3.1.0-1
dotnet-runtime-3.1.x86_64 0:3.1.0-1 dotnet-runtime-deps-3.1.x86_64 0:3.1.0-1

Complete!

Apache をインストール

[root@ip- ~]# sudo yum update -y
[root@ip- ~]# sudo yum -y install httpd mod_ssl

アプリ発行フォルダにパッケージする PC作業

コマンドプロンプトを開いてasp.net core mvc のプロジェクトフォルダに移動 フォルダ名は任意で。
dotnetコマンドはVisual Studio 2019インストールにて自動でインストールされたものと思われる

D:\www\netcore-web>dotnet publish --configuration Release
.NET Core 向け Microsoft (R) Build Engine バージョン 16.4.0+e901037fe
Copyright (C) Microsoft Corporation.All rights reserved.

D:\www\netcore-web\netcore-web.csproj の復元が 90.25 ms で完了しました。
netcore-web -> D:\www\netcore-web\bin\Release\netcoreapp3.1\netcore-web.dll
netcore-web -> D:\www\netcore-web\bin\Release\netcoreapp3.1\netcore-web.Views.dll
netcore-web -> D:\www\netcore-web\bin\Release\netcoreapp3.1\publish\
D:\www\netcore-web\bin\Release\netcoreapp3.1\publish\ ← publish内をLinuxにコピーする

「dotnet publish」コマンドはデフォルトで「フレームワークに依存する展開 (FDD)」とのことです。
「FDD では、アプリ、およびサードパーティの依存関係のみを展開します。 アプリでは、ターゲット システム上に存在するバージョンの .NET Core が使われます。 これは、.NET Core および .NET Core をターゲットとする ASP.NET Core アプリの既定の展開モデルです。」

公開サーバーにアプリケーションをデプロイ PC作業

winscp でPCからLinuxにコピーした(winscp については後日投稿検討)
D:\www\netcore-web\bin\Release\netcoreapp3.1\publish\ → Linux:/var/www/netcore1/
コピー後の Linux のアプリケーションフォルダの内容

[root@ip- netcore1]# pwd
/var/www/netcore1
[root@ip- netcore1]# ls -l
total 348
-rw-r--r-- 1 root root 162 Dec 22 12:02 appsettings.Development.json
-rw-r--r-- 1 root root 192 Dec 22 12:02 appsettings.json
-rw-r--r-- 1 root root 106562 Dec 25 12:59 netcore-web.deps.json
-rw-r--r-- 1 root root 9216 Dec 25 12:58 netcore-web.dll
-rw-r--r-- 1 root root 169984 Dec 25 12:58 netcore-web.exe
-rw-r--r-- 1 root root 1936 Dec 25 12:58 netcore-web.pdb
-rw-r--r-- 1 root root 224 Dec 25 12:59 netcore-web.runtimeconfig.json
-rw-r--r-- 1 root root 35840 Dec 25 12:59 netcore-web.Views.dll
-rw-r--r-- 1 root root 3604 Dec 25 12:59 netcore-web.Views.pdb
-rw-r--r-- 1 root root 555 Dec 25 12:59 web.config
drwxr-xr-x 5 root root 57 Jan 12 05:14 wwwroot

公開用にDNSの設定

ドメインもタダではないのでサブドメインで設定。検証用だし。

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

/etc/httpd/conf.d/netcore-web.conf 作成

[root@ip- conf.d]# cat netcore-web.conf
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>

<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ServerName xxx.domain
ServerAlias *.xxx.domain
ErrorLog /var/log/httpd/netcore-web-error.log
CustomLog /var/log/httpd/netcore-web-access.log common
</VirtualHost>

apache構成のテスト

[root@ip- ~]# service httpd configtest
Syntax OK

これでクライアントのブラウザからの要求をApacheリバースプロシキーがKestrel ASP.NET Core アプリ (http://127.0.0.1:5000) に転送するようになったはずです。

ブラウザから公開できたか確認

まず公開サーバーのLinuxにてアプリを起動する

[root@ip- netcore1]# dotnet netcore-web.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/netcore1

クライアントブラウザから urlを入力してアクセスしてみる

http://xxx.domain

Welcome がでた→正常に動作している様だ

# dotnet netcore-web.dll これが起動してないと

httpsの設定がまだないので

https://xxx.domain

apacheの画面になってしまう

ApacheがKestrel プロセスを管理する様に設定 Linux作業

[root@ip- netcore1]# dotnet netcore-web.dll

この様に毎回 dll ファイルを起動するのは非現実的
apache リバースプロシキーにアクセスが来たら自動でプロセスが起動するようにサービスを起動しておく

[root@ip- system]# pwd
/etc/systemd/system

[root@ip- system]# cat kestrel-netcore-web.service
[Unit]
Description=Example .NET Web API App running on CentOS 7

[Service]
WorkingDirectory=/var/www/netcore1
ExecStart=/usr/bin/dotnet /var/www/netcore1/netcore-web.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@ip- ~]# systemctl start kestrel-netcore-web.service

サービスの状態確認

[root@ip- ~]# systemctl status -l kestrel-netcore-web.service
● kestrel-netcore-web.service - Example .NET Web API App running on CentOS 7
Loaded: loaded (/etc/systemd/system/kestrel-netcore-web.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2020-01-21 13:41:38 UTC; 1min 23s ago
Main PID: 2140 (dotnet)
CGroup: /system.slice/kestrel-netcore-web.service
mq2140 /usr/bin/dotnet /var/www/netcore1/netcore-web.dll

Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: No XML encryptor configured. Key {} may be persisted to storage in unencrypted form.
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: Now listening on: http://localhost:5000
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: Application started. Press Ctrl+C to shut down.
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: Hosting environment: Production
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:41:38 ip-.ap-northeast-1.compute.internal dotnet-example[2140]: Content root path: /var/www/netcore1

disabled が出てるのでサービスを一時停止

[root@ip- ~]# systemctl stop kestrel-netcore-web.service

サービスを有効にする

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

サービスの状態確認

[root@ip- ~]# systemctl status -l kestrel-netcore-web.service
● kestrel-netcore-web.service - Example .NET Web API App running on CentOS 7
Loaded: loaded (/etc/systemd/system/kestrel-netcore-web.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2020-01-21 13:51:17 UTC; 5min ago
Main PID: 2413 (dotnet)
CGroup: /system.slice/kestrel-netcore-web.service
mq2413 /usr/bin/dotnet /var/www/netcore1/netcore-web.dll

Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: No XML encryptor configured. Key {} may be persisted to storage in unencrypted form.
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Now listening on: http://localhost:5000
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Application started. Press Ctrl+C to shut down.
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Hosting environment: Production
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Content root path: /var/www/netcore1

ログを表示する
Kestrel を使う Web アプリは systemd を使って管理されるため、イベントとプロセスは中央のジャーナルに記録されます。 ただし、このジャーナルには、systemd によって管理されるすべてのサービスとプロセスのエントリが含まれます。 kestrel-netcore-web.service 固有の項目を表示するには、次のコマンドを使用します。

[root@ip- ~]# journalctl -fu kestrel-netcore-web.service
-- Logs begin at Sun 2019-12-22 13:51:26 UTC. --
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: No XML encryptor configured. Key {} may be persisted to storage in unencrypted form.
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Now listening on: http://localhost:5000
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Application started. Press Ctrl+C to shut down.
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Hosting environment: Production
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: info: Microsoft.Hosting.Lifetime[0]
Jan 21 13:51:18 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Content root path: /var/www/netcore1
Jan 21 14:07:06 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Jan 21 14:07:06 ip-.ap-northeast-1.compute.internal dotnet-example[2413]: Failed to determine the https port for redirect.

感想

これで .net core ではあるが ASP.NET Core Web アプリを安価な Linux VPS で公開できてスッキリ!
ASP.NETの公開で高価な Windows VPS の呪縛から抜け出せそうだ。
いい感じになってきた~!

コメント