【ASP.NET MVC】LinuxサーバーにWebアプリをデプロイしてみた①【.NET5Runtimeインストール編】

技術

オンラインビンゴアプリ

会社の有志数名とオンラインビンゴアプリを作りました。
ASP.NET MVC 5 で作ったWebアプリです。

若手社員の学習という意味合いもあり、業務の合間にミーティングしたり、休日などを使って実装やレビューを進め徐々に作り上げてきて、いよいよ完成というところまで来ました。

そこで、会社のみんなでテストプレイを兼ねてオンラインビンゴ大会を開催してみようということになりました。

もちろんオンラインビンゴなので、オンラインでの開催です。
全員自宅から参加することになります。

となると当然、作ったアプリをサーバーにデプロイしてアクセスできる必要があるわけです。

サーバーは会社のサーバーを使わせてもらえることになりました。
といってもサーバーに直接デプロイするのではなく、VMWareで仮想マシンを作ってLinuxをインストールしてそこにデプロイするような構成になります。

何気に、「LinuxにASP.NETをデプロイする」ってやったことないので、会社のサーバーで作業する前にDocker上にデプロイしてみようと思います。

そんなこんなで手順を調べながらやってみました。
ちなみに最終的な構成はこうなりました。

  • OS は Linux(Ubuntu 22.04.3 LTS)
  • .NET Runtime(5.0.17)でSDKはインストールしない
  • Nginx 1.18.0 をリバースプロキシサーバーとする

リリースビルド と Dockerコンテナ

何はともあれ、まずは作成したWebアプリ(以下OnlineBingoアプリと呼称)をReleaseビルドしなくてはいけません。
.NET5のSDKがインストールされている端末(ほとんどの場合は開発マシンと同じですね)に、OnlineBingoアプリのソースコードを保存して、プロジェクトファイル「OnlineBingo.csproj」の保存されているディレクトリで下記のコマンドを実施します。

dotnet publish --configuration Release

bin/Release/net5.0ディレクトリにたくさんのファイルとフォルダが作成されて、その中にpublishというフォルダがあるはずです。
このpublishフォルダをまるっとサーバーへ持って行けばいいってわけですね。

次にLinuxがインストールされているDockerコンテナを作ります。
Docker Desktopは既にインストールされています。

docker run -itd --name nginx_test -p 80:80 -v $PWD\src:/usr/src ubuntu:22.04

このコマンドでUbuntu 22.04.2がインストールされているDockerコンテナができます。

コマンドを実行した時のディレクトリにはsrcディレクトリを作っておきます。
ここでDockerコンテナとファイルを共有できます。つまり、このsrcディレクトリに先ほど作ったpublishフォルダをコピーして持ってくることでDockerコンテナにリリースビルドされたモジュールを持ち込めるという寸法です。

ASP.NET 5 を Linux にインストール

いつも通り、DockerコンテナにVSCodeの「Remote Development」拡張を使ってアクセスします。

ASP.NET 5 をLinuxで実行するためにはまずRuntimeをインストールする必要があります。
Microsoftのページに手順がありました。

パッケージ マネージャーを使用せずに Linux に .NET をインストールする - .NET
パッケージ マネージャーを使用せずに、Linux に .NET SDK と .NET ランタイムをインストールする方法を示します。 インストール スクリプトを使用するか、手動でバイナリを抽出します。

幾つか方法があるみたいですが、インストール用のスクリプトがあるようなのでそれを使うのが一番簡単そうです。
Microsoftのページに記載の通りの手順で進めます。

下記のコマンドを順に実行します。ちなみにrootユーザーです。

wgetがインストールされてないのでインストールしておきます。

apt-get update && apt-get install -y wget

wget がインストールできたら、次はこれです。

wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh

カレントディレクトリにdotnet-install.shというスクリプトファイルがダウンロードできました。

ダウンロードしたスクリプトは実行権限がついてないので、実行権限をつけます。

chmod +x ./dotnet-install.sh

最後にこのコマンドでいよいよ.NET 5 の Runtime をインストールします。

./dotnet-install.sh --runtime aspnetcore --version 5.0.17

今回は開発環境ではなく実行環境なのでSDKは不要です。
ASP.NETのランタイムだけが必要なので--runtime aspnetcoreというスイッチを指定しています。
また、.NET 5 ということで--version 5.0.17も指定しました。

無事インストールできたら下記のコマンドでバージョンを確認します。

dotnet --info

・・・失敗しますね。

bash: dotnet: command not found

どうやらPATHが通っていないみたい。どこにインストールされたんだろう?

探してみるとありました。「/root/.dotnet」ディレクトリです。
どうもダウンロードしたインストールスクリプトでは$HOME/.dotnetにデフォルトでインストールするらしいです。

このインストール先を任意のパスにしたい場合は「dotnet-install.sh」スクリプトの実行前にDOTNET_INSTALL_DIRという環境変数にパスを設定しておけばいいみたいです。

今回はこのまま「/root/.dotnet」にインストールされたdotnetを使うことにします。
下記のコマンドでパスを通しておきます。

export DOTNET_ROOT=/root/.dotnet
export PATH=$PATH:/root/.dotnet:/root/.dotnet/tools

bashを切り替えてもパスが通るようにするためには/root/.bash_profileというファイルを作って、このコマンドを書いておけばOKです。

もう一度バージョンを確認。

dotnet --info

Host (useful for support):
Version: 5.0.17
Commit: 6a98414363

.NET SDKs installed:
No SDKs were found.

.NET runtimes installed:
Microsoft.AspNetCore.App 5.0.17 [/root/.dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.17 [/root/.dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download

今度は無事にバージョンを確認できました。
SDKは入っていないのでNo SDKs were found.となっています。

では早速OnlineBingoアプリを実行してみます。
Releaseビルドされた OnlineBingoアプリ はホストとマウントしている「/usr/src」配下の publish ディレクトリにあるんでした。

cd /usr/src/publish
dotnet OnlineBingo.dll

このコマンドで実行できるはずですが・・・エラーになってしまいました。

Process terminated. Couldn’t find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.

ICUパッケージなるものをインストールするかグローバリゼーションサポート(国際化対応?)を無効にすればいいらしい。

今回はグローバリゼーションサポートの無効化で対応します。

「Set the configuration flag System.Globalization.Invariant to true」

と書かれています。

OnlineBingoのソースコードに戻って プロジェクトファイル(OnlineBingo.csproj)にこれを追加します。

  <ItemGroup>
    <RuntimeHostConfigurationOption Include="System.Globalization.Invariant" Value="true" />
  </ItemGroup>

再度、publishします。

dotnet publish --configuration Release

出来上がったpublishフォルダをDockerコンテナとマウントしているフォルダにコピーしてきます。

では、もう一度 OnlineBingoアプリ を実行してみましょう。

dotnet OnlineBingo.dll

・・・またエラーになりました。
ただし、先ほどとは内容が変わっているみたいです。

No usable version of libssl was found
Aborted

.NET 5 の場合は OpenSSL 1.1 をインストールする必要があるらしいです。

openssl version -a

このコマンドでバージョンを確認してみると「OpenSSL 3.0.2」が入っているみたいでした。
.NET 6 以降なら OpenSSL 3 でいいらしいのですが、.NET 5 では バージョン 1.1 が必要みたいです。

OpenSSL 1.1 のインストール

ということで、続いては OpenSSL 1.1 をインストールします。

OpenSSLのインストールは基本的にソースコードをダウンロードしてビルドする、という流れになります。
なので、まずはビルドできる環境を作る必要があります。

ビルドにはbuild-essentialというツールをインストールしておけばOKです。

apt install -y build-essential

これだけでビルドの準備は完了。
あとはソースコードをダウンロードしてくるだけです。

wget https://www.openssl.org/source/openssl-1.1.1v.tar.gz -O openssl-1.1.1v.tar.gz
tar zxf openssl-1.1.1v.tar.gz
cd openssl-1.1.1v

wget でOpenSSLのホームページからダウンロードしてtarコマンドで解凍しました。
解凍されたopenssl-1.1.1vに移動しておきます。

解凍したファイルの中にconfigというツールがあるのでこれでビルドの設定をします。

./config --prefix=/usr/local --openssldir=/usr/local/ssl --shared

--prefixでインストール先のディレクトリを指定するようです。
インストール先に特に決まりはないらしいので、今回は「/usr/local」にしました。
また--openssldirには「/usr/local/ssl」と指定しました。

では、いよいよビルド、そしてインストール。

make
make test
make install

こちらの記事を参考にさせてもらいました。

最後に「LD_LIBRARY_PATH」という環境変数にlibssl.so.1.1が保存されているパスを指定します。

libssl.so.1.1 は config ツールで「–prefix=/usr/local」と指定していた場合は「/usr/local/lib」に保存されているはずです。

export LD_LIBRARY_PATH=/usr/local/lib

これで OpenSSL 1.1 がインストールできて dotnet から利用できるようになったはずです。

それでは三度、OnlineBingoアプリの実行してみます。

dotnet OnlineBingo.dll

今度は無事実行できました。

まだ途中ですが、

思いのほかに、記事が長くなってしまったので、続きは次の記事に記すことにします。

今回の記事ではとりあえずReleaseビルドしたASP.NET mvcのアプリケーションが Linux で起動できることが確認できました。

ただし、これはASP.NETに含まれているKestrelというサーバー上で動作しているだけです。
Kestrelサーバーはそのまま公開してしまうとセキュリティ的にいろいろ問題があるとのことで、通常はリバースプロキシサーバーを立てて、バックエンドで動作させる構成にするらしいです。

というわけで次回は Nginx でリバースプロキシサーバーを立てて OnlineBingoアプリ と連動させることに挑戦してみます。

ぜひぜひ、お楽しみに!!

コメント

タイトルとURLをコピーしました