AWS Lightsail のやっすいやつで CentOS 7 のインスタンスを立てたので、ASP.NET Core 2.2でWebサービスを作ってみる。
環境等
- CentOS 7.6
- VisualStudio Community 2019
- 開発はローカルのWindowsマシンで行う
- 「ASP.NET と Web 開発」ワークロードがインストールされていること
- Apache 2.4.6
- ASP.NET Core には Kestrel っていうデフォルトの Web サーバがついてくる
- これだけでも動かせるはずだが、あんまりみんな使ってなさそう
- Apache をリバースプロキシとして、リクエストを Kestrel に流すようにする
- ASP.NET Core には Kestrel っていうデフォルトの Web サーバがついてくる
CentOS に ASP.NET Core 2.2をインストール
サーバ上でコンパイルとかするなら SDK を入れる必要があるが、今回は runtime だけ入れることにする。
なお .NET Core アプリは self-contained でビルドしてruntimeごと配布アプリに含めることもできるんだけど、 ASP.NET Core でも同じことできるんかな。
とりま今回はそれはやらず、サーバにあらかじめインストールしておきます。
参考)
$ sudo yum update $ sudo yum install aspnetcore-runtime-2.1
サービスアプリ作成
チュートリアル: ASP.NET Core で Web API を作成するのとおりにやっていきます。
と Todo タスクの登録・参照 API ができあがる。
Apache インストールと設定
参考)
サーバに Apache をインストールし、とりあえず雑に全部 http://localhost:5000/
に受け流す。
$ sudo yum -y install httpd $ sudo vi /etc/httpd/conf/httpd.conf
### ここからコメントアウト ### # <Directory /> # AllowOverride none # Require all denied # </Directory> ### ここまでコメントアウト ### ### ここから追加 ProxyPreserveHost On ProxyPass / http://localhost:5000/ ProxyPassReverse / http://localhost:5000/ ### ここまで追加
起動。
$ sudo systemctl start httpd
サーバへのデプロイ
VisualStudio から「発行」で FolderProfile を選択し、適当なローカルのフォルダを指定して実行。
吐き出されたファイル一式を、とりあえず手作業でサーバの適当な場所にコピーする。
ターミナルでサーバにログインし、作成したアプリの dll(仮に todoapp.dll
)を置いたディレクトリに移動してアプリ起動。
$ dotnet todoapp.dll Hosting environment: Production Content root path: /path/to/todoapp Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.
listening on: http://localhost:5000 とのことなので、これで 80 ポートで受け付けたリクエストが 5000 ポートで起動中のアプリに渡るようになったはず。
ブラウザから GET メソッドの URL にアクセスすれば、チュートリアルで作った todo の JSON が返ってくるはず。
SSL化
https での接続を有効にします。
参考) ApacheでLinux上でASP.NETコアをホストする - アプリをセキュリティで保護する
最初にファイアウォールに HTTPS 用のポート(443)を開けておく。
AWS Lightsail の場合は、コンソール画面の「ネットワーキング」タブから。
つづいて Apache の設定。
mod_ssl をインストール。
$ sudo yum -y install mod_ssl
参照先ページでは mod_rewrite を使って http → https の URL 書き換えをやっているが、ここでは割愛。
httpd.conf で、先ほど追加したリバースプロキシ設定の下に SSL の設定を追記する。
$ sudo vi /etc/httpd/conf/httpd.conf
SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4 SSLCertificateFile /etc/pki/tls/certs/localhost.crt SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
この例だとローカルの証明書を使ってるので、このままだとブラウザで警告が表示される。
本来はちゃんと署名されたやつを使いましょう。
サービス再起動。
$ sudo systemctl restart httpd
これで、https の URL で GET できるようになり、http の URL だと 400 Bad Request が返るようになっているはず。
データ永続化
チュートリアルの TODO アプリのままだと、サーバを落としたタイミングでそれまでの登録データが全部リセットされてしまうので、データベースに値を保持するように変えてみる。
サーバに DB たてるぞって時点で、一旦めんどくせぇなーってなっちゃうんだよな。インフラ筋が足りない。
てわけで、簡単に SQLite でやることにします。
このへんは前にもちょっと書いた。
ASP.NET Core × Entity Framework × SQLite - OITA: Oika's Information Technological Activities
NuGet から以下2つインストール。
- Microsoft.EntityFrameworkCore.Tools
- Microsoft.EntityFrameworkCore.Sqlite
チュートリアルの中ですでに DbContext クラスとかは作ってるので、変える必要があるのは Startup.cs 内、 UseInMemoryDatabase
とやっていたところだけ。
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // services.AddDbContext<TodoContext>(opt => opt.UseInMemoryDatabase("TodoList")); services.AddDbContext<TodoContext>(opt => opt.UseSqlite(@"Data Source='data.db'")); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
VS のパッケージマネージャーコンソールから下記コマンドで DB ファイル(data.db)を生成しておく。
PM> Add-Migration InitTable PM> Update-Database
デプロイの際に、生成された data.db も忘れずに配備する。上記の書き方だと dll と同じ場所に配置。
VSで「発行」したときに出力される SQLite 系の dll も同じように全部配備する。
以上
とりあえずこんなところか。以下積み残し(当分やらないと思うけど)
- リバースプロキシの真面目な設定
- SSL の真面目な設定
- DB の真面目な構築
- アプリのサービス化と監視
- CI/CD の構築