Docker 環境で C# ASP.NET Core Blazor Webアプリを起動する (WebAssembly)
こんにちは、@studio_meowtoon です。今回は、WSL Ubuntu 22.04 の Docker 環境で C# ASP.NET Core Blazor Web アプリケーションをコンテナとして起動する方法を紹介します。
目的
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
実現すること
ローカル環境の Ubuntu の Docker 環境で、Dockerfile からビルドした C# ASP.NET Core Blazor Web アプリのカスタムコンテナを起動します。
技術トピック
Dockerfile とは?
こちらを展開してご覧いただけます。
Dockerfile リファレンス
Dockerfile は、Docker イメージをビルドするためのファイルであり、Docker コンテナの構成情報を記述するためのテキストファイルです。Dockerfile には、ベースイメージ、パッケージのインストール、環境変数の設定、ファイルのコピーなどの命令が含まれます。
また、Docker コンテナに使用するベースイメージとして、Ubuntu を選択することが一般的です。そのため、Ubuntu の知識があると Dockerfile を理解しやすくなります。
開発環境
- Windows 11 Home 22H2 を使用しています。
WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。
WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
.NET SDK ※ こちらの関連記事からインストール方法をご確認いただけます
$ dotnet --list-sdks
7.0.202 [/usr/share/dotnet/sdk]
$ dotnet --version
7.0.202
Docker ※ こちらの関連記事からインストール方法をご確認いただけます
$ docker --version
Docker version 23.0.1, build a5ee5b1
この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
作成する Web アプリケーションの仕様
No | エンドポイント | HTTPメソッド | MIME タイプ |
---|---|---|---|
1 | / | GET | text/html |
Hello World を表示する手順
C# ASP.NET Core Blazor Web アプリの作成
こちらの関連記事で手順がご確認いただけます。
ここまでの手順で、ローカル環境の Ubuntu でアプリの DLL ファイルを起動することができました。
プロジェクトフォルダに移動
プロジェクトフォルダに移動します。
※ ~/tmp/BlazorApp をプロジェクトフォルダとします。
$ cd ~/tmp/BlazorApp
ライブラリの削除
静的ビルドのために、 Microsoft.AspNetCore.Components.WebAssembly.DevServer を削除します。
$ dotnet remove package Microsoft.AspNetCore.Components.WebAssembly.DevServer
アプリのビルド
プロジェクトの成果物を一旦削除します。
$ rm -rf bin obj out
アプリケーションをビルドして出力します。
※ out/wwwroot/_framework/BlazorApp.dll が作成されます。
$ dotnet publish -c Release -o out
ここまでの手順で、ローカル環境の Ubuntu に DLL ファイル形式のアプリをビルドすることができました。
コンテナイメージの作成
WebAssembly として静的ビルドした Web アプリをホストするため、Web サーバーとして Nginx を使用します。
nginx.conf を作成します。
$ vim nginx.conf
ファイルの内容
events { }
http {
include mime.types;
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html = 404;
}
}
}
Dockerfile を作成します。
$ vim Dockerfile
ファイルの内容
# from the base image of a nginx on alpine linux.
FROM nginx:alpine
# create a work dir.
WORKDIR /usr/share/nginx/html
# copy a wasm app.
COPY /out/wwwroot .
# copy an nginx conf.
COPY nginx.conf /etc/nginx/nginx.conf
Docker デーモンを起動します。
$ sudo service docker start
* Starting Docker: docker [ OK ]
Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。
コンテナイメージをビルドします。
$ docker build --no-cache -t app-hello-blazor-wasm .
コンテナイメージを確認します。
$ docker images | grep app-hello-blazor-wasm
REPOSITORY TAG IMAGE ID CREATED SIZE
app-hello-blazor-wasm latest fa24acc86d22 9 seconds ago 55.9MB
ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナイメージをビルドすることができました。
コンテナを起動
ローカルでコンテナを起動します。
$ docker run --rm \
--name app-local \
-p 8080:80 app-hello-blazor-wasm
ここまでの手順で、ローカル環境の Docker でアプリのカスタムコンテナを起動することができました。
コンテナの動作確認
Web ブラウザで以下の URL にアクセスします。
http://localhost:8080/
Web ブラウザに Hello World!" と表示されました。
コンテナの状態を確認してみます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6af2bd419965 app-hello-blazor-wasm "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp app-local
コンテナに接続
別ターミナルからコンテナに接続します。
※ コンテナを停止するときは ctrl + C を押します。
$ docker exec -it app-local sh
コンテナに接続後にディレクトリを確認します。
※ コンテナから出るときは ctrl + D を押します。
# pwd
/usr/share/nginx/html
# ls -lah
total 32K
drwxr-xr-x 1 root root 4.0K Mar 27 05:08 .
drwxr-xr-x 1 root root 4.0K Feb 11 10:03 ..
-rw-r--r-- 1 root root 497 Dec 13 18:23 50x.html
drwxr-xr-x 2 root root 12.0K Mar 27 05:08 _framework
-rw-r--r-- 1 root root 248 Mar 27 04:21 index.html
_framework ディレクトリの中身を確認します。
# cd _framework
# apk add tree
# tree
.
├── BlazorApp.dll
├── BlazorApp.dll.br
├── BlazorApp.dll.gz
├── BlazorApp.pdb.gz
├── Microsoft.AspNetCore.Components.Web.dll
├── Microsoft.AspNetCore.Components.Web.dll.br
├── Microsoft.AspNetCore.Components.Web.dll.gz
├── Microsoft.AspNetCore.Components.WebAssembly.dll
├── Microsoft.AspNetCore.Components.WebAssembly.dll.br
├── Microsoft.AspNetCore.Components.WebAssembly.dll.gz
├── Microsoft.AspNetCore.Components.dll
├── Microsoft.AspNetCore.Components.dll.br
├── Microsoft.AspNetCore.Components.dll.gz
├── Microsoft.Extensions.Configuration.Abstractions.dll
├── Microsoft.Extensions.Configuration.Abstractions.dll.br
├── Microsoft.Extensions.Configuration.Abstractions.dll.gz
├── Microsoft.Extensions.Configuration.Json.dll
├── Microsoft.Extensions.Configuration.Json.dll.br
├── Microsoft.Extensions.Configuration.Json.dll.gz
├── Microsoft.Extensions.Configuration.dll
├── Microsoft.Extensions.Configuration.dll.br
├── Microsoft.Extensions.Configuration.dll.gz
├── Microsoft.Extensions.DependencyInjection.Abstractions.dll
├── Microsoft.Extensions.DependencyInjection.Abstractions.dll.br
├── Microsoft.Extensions.DependencyInjection.Abstractions.dll.gz
├── Microsoft.Extensions.DependencyInjection.dll
├── Microsoft.Extensions.DependencyInjection.dll.br
├── Microsoft.Extensions.DependencyInjection.dll.gz
├── Microsoft.Extensions.Logging.Abstractions.dll
├── Microsoft.Extensions.Logging.Abstractions.dll.br
├── Microsoft.Extensions.Logging.Abstractions.dll.gz
├── Microsoft.Extensions.Logging.dll
├── Microsoft.Extensions.Logging.dll.br
├── Microsoft.Extensions.Logging.dll.gz
├── Microsoft.Extensions.Options.dll
├── Microsoft.Extensions.Options.dll.br
├── Microsoft.Extensions.Options.dll.gz
├── Microsoft.Extensions.Primitives.dll
├── Microsoft.Extensions.Primitives.dll.br
├── Microsoft.Extensions.Primitives.dll.gz
├── Microsoft.JSInterop.WebAssembly.dll
├── Microsoft.JSInterop.WebAssembly.dll.br
├── Microsoft.JSInterop.WebAssembly.dll.gz
├── Microsoft.JSInterop.dll
├── Microsoft.JSInterop.dll.br
├── Microsoft.JSInterop.dll.gz
├── System.Collections.Concurrent.dll
├── System.Collections.Concurrent.dll.br
├── System.Collections.Concurrent.dll.gz
├── System.Collections.dll
├── System.Collections.dll.br
├── System.Collections.dll.gz
├── System.ComponentModel.dll
├── System.ComponentModel.dll.br
├── System.ComponentModel.dll.gz
├── System.Linq.dll
├── System.Linq.dll.br
├── System.Linq.dll.gz
├── System.Memory.dll
├── System.Memory.dll.br
├── System.Memory.dll.gz
├── System.Net.Http.dll
├── System.Net.Http.dll.br
├── System.Net.Http.dll.gz
├── System.Net.Primitives.dll
├── System.Net.Primitives.dll.br
├── System.Net.Primitives.dll.gz
├── System.Private.CoreLib.dll
├── System.Private.CoreLib.dll.br
├── System.Private.CoreLib.dll.gz
├── System.Private.Uri.dll
├── System.Private.Uri.dll.br
├── System.Private.Uri.dll.gz
├── System.Runtime.InteropServices.JavaScript.dll
├── System.Runtime.InteropServices.JavaScript.dll.br
├── System.Runtime.InteropServices.JavaScript.dll.gz
├── System.Runtime.dll
├── System.Runtime.dll.br
├── System.Runtime.dll.gz
├── System.Text.Encodings.Web.dll
├── System.Text.Encodings.Web.dll.br
├── System.Text.Encodings.Web.dll.gz
├── System.Text.Json.dll
├── System.Text.Json.dll.br
├── System.Text.Json.dll.gz
├── blazor.boot.json
├── blazor.boot.json.br
├── blazor.boot.json.gz
├── blazor.webassembly.js
├── blazor.webassembly.js.br
├── blazor.webassembly.js.gz
├── dotnet.7.0.4.11onvycki2.js
├── dotnet.7.0.4.11onvycki2.js.br
├── dotnet.7.0.4.11onvycki2.js.gz
├── dotnet.timezones.blat
├── dotnet.timezones.blat.br
├── dotnet.timezones.blat.gz
├── dotnet.wasm
├── dotnet.wasm.br
├── dotnet.wasm.gz
├── icudt.dat
├── icudt.dat.br
├── icudt.dat.gz
├── icudt_CJK.dat
├── icudt_CJK.dat.br
├── icudt_CJK.dat.gz
├── icudt_EFIGS.dat
├── icudt_EFIGS.dat.br
├── icudt_EFIGS.dat.gz
├── icudt_no_CJK.dat
├── icudt_no_CJK.dat.br
└── icudt_no_CJK.dat.gz
top コマンドで状況を確認します。
# top
Mem: 6738496K used, 1210924K free, 134652K shrd, 149600K buff, 5228784K cached
CPU: 0% usr 0% sys 0% nic 99% idle 0% io 0% irq 0% sirq
Load average: 0.00 0.02 0.03 1/410 37
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
30 1 nginx S 7816 0% 2 0% nginx: worker process
1 0 root S 7576 0% 7 0% nginx: master process nginx -g daemon off;
31 0 root S 1692 0% 4 0% sh
37 31 root R 1620 0% 10 0% top
コンテナの情報を表示してみます。
# cat /etc/*-release
3.17.2
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.17.2
PRETTY_NAME="Alpine Linux v3.17"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
このコンテナは Alpine Linux をベースに作成されています。つまり、Alpine Linux と同じように扱うことができます。
まとめ
WSL Ubuntu の Docker 環境で、Dockerfile からビルドした C# ASP.NET Core Blazor Web アプリのカスタムコンテナを起動することができました。
クラウド開発においては、Dockerfile の理解は重要です。自動ビルドツールもありますが、手動で書く必要があるケースもあります。Ubuntu を使うと Linux の知識も身に付きます。最初は難しく感じるかもしれませんが、徐々に進めていけば自信を持って書けるようになります。
どうでしたか? WSL Ubuntu で、C# ASP.NET Core Blazor Web アプリケーションを Docker 環境でコンテナとして手軽に起動することができます。ぜひお試しください。今後も .NET の開発環境などを紹介していきますので、ぜひお楽しみにしてください。
推奨コンテンツ