CentOS上にASP.NET Coreアプリを立ち上げる

# はじめに

　普段からC#を使用しているので、VisualStudioさえあればすぐに動かせるASP.NETはウェブ開発をするうえで有力な選択肢なのですが、Linuxのサーバで動かないという欠点のため採用しづらいのが実情です。
　ASP.NET Coreがあるじゃない、と言っても実際のところちゃんと動くの？環境構築めっちゃ大変なんじゃないの？という疑問が頭をよぎるので、試しにCentOS上に構築してみました。
　動かしてみたアプリケーションはASP.NET Core Identityを利用しており、postgresも一緒に構築しています。

# 構築

## バージョン

.NET Core 2.1
ASP.NET MVC 2.1.2
CentOS 7.2
Apache httpd 2.4.6
PostgreSQL 10.5

## 全体構成

　Apacheを使ってASP.NET Coreのアプリを立ち上げるとき、Microsoftの公式サイトではKestrelという.NET標準のウェブサーバを使用していたので、ここでも同じ構成にします。
　つまり、Kestrelを使用してASP.NET Coreアプリを立ち上げ、httpdをリバースプロキシとして利用します。

## ステップ1：.NET Coreを入れる

　今回は専用のVPSを新しく契約したので、ピカピカのCentOSがインストールされている状態からのスタートになりました。
　まずは.NET Coreの[ダウンロードサイト](https://www.microsoft.com/net/download/dotnet-core/2.1)へ行きます。
普通はあまりないかもしれませんが、サーバ上でソースをビルドした方が簡単なため、SDKの方を入れました。ビルド済みのものを使用するのであればRuntimeの方を入れます。インストール方法はLinuxの項目のPackage Manager: Instructions に記載されているので、その通りに進めます。

```
sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
sudo yum update
sudo yum install dotnet-sdk-2.1
```

## ステップ2：アプリをビルドする

　上述の通りソースをサーバ上でビルドしたかったので、プロジェクトのホームディレクトリ（csprojが置いてあるところ）へ行って次のコマンドを叩きます。

```
dotnet publish --configuration Release
```

## ステップ3：DBアップデートを実行する

　続いて、同じくプロジェクトのホームディレクトリでマイグレーション実行します。postgresのインストール、必要なデータベースやロールの作成は済んでいるものと仮定します。
　ちなみに、私はpostgresのpeer認証をmd5認証に変更していなかったのでマイグレーションにこけてしまい、無駄に時間を使いました。

```
dotnet ef database update
```

　もう一つ余談ですが、何も考えずにpostgresを入れるとPostgreSQL 9.4あたりが入るのですが、使用しているNpgsqlがPostgreSQL 10.5向けのものだったため、やはりマイグレーションにこけました。バージョン揃えるの大事ですね。

## ステップ4：Kestrelを起動する

　Kestrelを起動するためのサービスを登録します。aspappのところは各自のアプリ名に変更してください。


```
sudo vim /etc/systemd/system/kestrel-aspapp.service
```

　内容は次のようになります。
　Microsoftによれば、ビルドしたアプリは/var以下に配置するのが一般的とのこと。ビルドするとプロジェクトのホームディレクトリ直下に/bin/Release/netcoreapp2.1/publishというフォルダが作成されるので、このフォルダの中身を/var/aspappにでもコピーしましょう。

```
[Unit]
Description=Example service file for ASP.NET Core application.

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

[Install]
WantedBy=multi-user.target
```

　サービスファイルを作成したらサービスを有効化します。

```
systemctl enable kestrel-aspapp.service
systemctl start kestrel-aspapp.service
```

　ステータスがこのようになればKestrelは正常に起動しています。

```
systemctl status kestrel-aspapp.service
* kestrel-aspapp.service - Example service file for ASP.NET Core application.
   Loaded: loaded (/etc/systemd/system/kestrel-aspapp.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2018-08-25 14:12:22 JST; 7h ago
 Main PID: 15762 (dotnet)
   CGroup: /system.slice/kestrel-aspapp.service
           `-15762 /usr/bin/dotnet /var/aspapp/aspapp.dll
```

## ステップ5：httpdに設定する

　httpdのインストール自体は完了して動く状態だと仮定します。
　まずは専用の設定ファイルを作成します。

```
sudo vim /etc/httpd/conf.modules.d/aspapp.conf
```

　設定ファイルには次のように書きます。
　ServerNameとServerAliasにはご自身で取得されたドメイン名を記入してください。

```
<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 www.aspapp.com
    ServerAlias *.aspapp.com
    ErrorLog ${APACHE_LOG_DIR}hellomvc-error.log
    CustomLog ${APACHE_LOG_DIR}hellomvc-access.log common
</VirtualHost>
```

　httpdを再起動して設定を反映したら終わりです。

```
sudo systemctl restart httpd
```

## おわり

　これで80番ポートにアクセスすればASP.NET Coreで作ったアプリにアクセスできるようになります。ポート開放やら必要な手続きをお忘れなく。
案外サーバ構築の手間が少なく、いい感じですね。あとはデプロイを自動化するバッチでも作ればストレスフリーなウェブ開発が出来そうです。

# 参考サイト

[Apache 搭載の Linux で ASP.NET Core をホストする](https://docs.microsoft.com/ja-jp/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-2.1&tabs=aspnetcore2x#prerequisites)