Blazor(C#)をDockerで動かす方法

Blazorとは、

> Blazor は、.NET を使って対話型のクライアント側 Web UI を構築するためのフレームワークです。
> ・JavaScript の代わりに C# を使って、優れた対話型 UI を作成します。
> ・.NET で記述された、サーバー側とクライアント側のアプリのロジックを共有します。
> ・モバイル ブラウザーを含めた広範なブラウザーのサポートのために、HTML および CSS として UI をレンダリングします。
> ・Docker などの最新のホスティング プラットフォームと統合します。
> https://docs.microsoft.com/ja-jp/aspnet/core/blazor/?view=aspnetcore-3.1

なるほど、すごいですね。

BlazorをDocker上で動かしてみたのでその手順をまとめたいと思います。

今回はASP.NET Core Blazor のホスティング モデルで構築したいと思います。
ブラウザ側ではWebAssembly ベースの .NET ランタイム(`Blazor WebAssembly`) が動作してます。

![dotnet-3.1.402](https://img.shields.io/badge/dotnet-3.1.402-brightgreen) ![docker-19.03.12](https://img.shields.io/badge/docker-19.03.12-brightgreen)

## まずはプロジェクトを作成します

下記コマンドを実行してください。プロジェクト名は`BrazorwasmDotNetCoreHostedWithDocker`としています。

```powershell
dotnet new blazorwasm --hosted -o BrazorwasmDotNetCoreHostedWithDocker
```

すると、

![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624898/7a0ff70d-e3f3-2b26-5019-bf3e9447bd24.jpeg)

こんな感じで、サーバ側、クライアント側、共通部分のプロジェクトができるかと思います。

## ローカルで動作確認します

```powershell
cd BrazorwasmDotNetCoreHostedWithDocker
dotnet publish
```

うまくいっていれば、プロジェクトは以下の`Server\bin\Debug\netcoreapp3.1\publish`に実行ファイルが出力されているはずです。
その配下に`wwwroot`がいることを確認してください。そこが公開フォルダとなります。

起動いたします。

```powershell
cd Server\bin\Debug\netcoreapp3.1\publish
dotnet BrazorwasmDotNetCoreHostedWithDocker.Server.dll
```

こんな感じでログが出力されます。
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624898/a9ea9e72-2068-217c-5bca-7dd3c86ab070.jpeg)
その中にContent root pathというものがあるかと思いますが、そこがコンテントルートとなり、その下のwwwrootが公開フォルダとなります。

ブラウザ上から`http://localhost:5000/`にアクセスして、下記のようなページが表示されれば成功です。
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624898/0bfa39e6-7bc4-a8ed-7228-f19b62c64dd8.jpeg)

上記と同じことをDocker上でします。

## Dockerfile作ります

プロジェクトのトップに下記のようなDockerファイルを作成します。

```dockerfile:Dockerfile
# コンパイルします
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app
# 配下のもの全部コピーしてrestoreします
COPY . ./
RUN dotnet restore
# outディレクトリに発行します
RUN dotnet publish -c Release -o out

# 実行用Imageを用意します
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "BrazorwasmDotNetCoreHostedWithDocker.Server.dll"]
```

実行用のイメージに関してですが、
コンテントルートパスはdotnetコマンド実行ディレクトリとなり、`/app`の直下に`wwwroot`を持ってくるように設定しております。

## Docker buildします

プロジェクト直下まで戻っていただいて、

```powershell
docker build -t brazorwasmdotnetcorehosted .
```

こちら実行します。`brazorwasmdotnetcorehosted`というイメージで作成しています。
`docker images`して、イメージができていれば成功です。
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624898/bc3ee554-f1f0-3e63-4940-61bc96699235.jpeg)

## Docker runします

```powershell
docker run -d -p 80:80 brazorwasmdotnetcorehosted:latest --rm
```

`http://localhost/`にアクセスすれば、先ほどのページが表示されるはずです。

## ちなみにスタンドアローン（静的コンテンツのみ）の場合は

最初のプロジェクトを作るときに、

```powershell
dotnet new blazorwasm -o BrazorwasmDotNetCoreStandAloneWithDocker
```
とし、Dockerfileで構築すればいけます。nginxで動かしています。

```dockerfile:Dockerfile
# コンパイルします
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app
# 配下のもの全部コピーしてrestoreします
COPY . ./
RUN dotnet restore
# outディレクトリに発行します
RUN dotnet publish -c Release -o out

FROM nginx:alpine
EXPOSE 80
COPY --from=build-env /app/out/wwwroot /usr/share/nginx/html
```