Azure Container Apps (ACA) に C# ASP.NET Core Blazor Webアプリをデプロイする (Docker Hub カスタムコンテナイメージ)

# Azure Container Apps (ACA) に C# ASP.NET Core Blazor Webアプリをデプロイする (Docker Hub カスタムコンテナイメージ)

こんにちは、@studio_meowtoon です。今回は、Azure Container Apps 環境で C# ASP.NET Core Blazor Web アプリケーションをコンテナとして起動する方法を紹介します。
![blazor_on_container-apps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/c47b0385-7981-a622-96ef-2dbb85099a54.png)

## 目的

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

https://qiita.com/studio_meowtoon/items/6119ab05d8b13527efd8

## 実現すること

Microsoft Azure Container Apps (ACA) に C# ASP.NET Core Blazor Web アプリケーションのカスタムコンテナイメージをデプロイします。  

:::note alert
この記事では、**Docker Hub** に公開する**パブリックアクセス可能なカスタムコンテナイメージ**を使用しています。実際のシステム開発では、どのレジストリからコンテナイメージを取得するかは異なる場合がありますので、適宜ご確認ください。
:::

## 技術トピック

### Microsoft Azure Container Apps (ACA) とは？  

<details>
<summary>こちらを展開してご覧いただけます。</summary>

### [Microsoft Azure Container Apps (ACA)](https://learn.microsoft.com/ja-jp/azure/container-apps/overview)

:::note info
Azure 上で実行されるコンテナアプリケーションのプラットフォームです。  

ACA は、Docker コンテナと Kubernetes クラスタの環境をサポートしており、開発者はコンテナイメージを作成して、Kubernetes リソースとしてデプロイすることができます。また、カスタムドメイン名をサポートしているため、自社のブランドを維持することができます。  

|メリット|説明|
|:--|:--|
|簡単なセットアップとデプロイ|ACA は、簡単なユーザーインターフェイスを備えており、数回のクリックでコンテナアプリケーションをセットアップしてデプロイすることができます。|
|スケーラビリティ|ACA は、自動的にスケーリングを行うことができます。アプリケーションに必要なリソースが増加した場合、ACA は自動的に必要なリソースを追加して処理を分散します。|
|セキュリティ|ACA は、コンテナアプリケーションを実行する際に必要なセキュリティ機能を提供しています。例えば Azure Active Directory との統合や、コンテナレベルでのアクセス制御などがあります。|
|コスト効率|ACA は、必要なときに必要なリソースを追加するため、無駄なリソースの使用を最小限に抑えることができます。また、必要なリソースに対してのみ支払いを行うため、コスト効率的に利用することができます。|
:::

</details>

## 開発環境

+ Windows 11 Home 22H2 を使用しています。  

:::note info
[WSL](https://learn.microsoft.com/ja-jp/windows/wsl/about) の Ubuntu を操作していきますので macOS の方も参考にして頂けます。  
:::

<details>

WSL (Microsoft Store アプリ版) [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/2aaa6579cb8e4fa1d874)

```sh
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
```

Ubuntu [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/2aaa6579cb8e4fa1d874)

```sh
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
```

.NET SDK [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/d68031c91462f6808dff)

```sh
$ dotnet --list-sdks
7.0.202 [/usr/share/dotnet/sdk]
$ dotnet --version
7.0.202
```

Docker [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/3bceee25ac67cc73ebbe)

```sh
$ docker --version
Docker version 23.0.1, build a5ee5b1
```

Azure CLI [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/9721041f9e6e3e987cf0)

```sh
$ az --version
azure-cli                         2.45.0
core                              2.45.0
telemetry                          1.0.8
```

</details>

:::note warn
この記事では基本的に **Ubuntu のターミナルで操作**を行います。**Vim を使用してコピペする方法**を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
:::

https://qiita.com/studio_meowtoon/items/7771ad48676926e41463

## 作成する Web アプリケーションの仕様

|No|エンドポイント|HTTPメソッド|MIME タイプ|
|:--|:--|:--|:--|
|1|/|GET|text/html|

## Hello World を表示する手順 

### C# ASP.NET Core Blazor Web アプリの作成  

こちらの関連記事で手順がご確認いただけます。

https://qiita.com/studio_meowtoon/items/63a4286a78df82a0556c

:::note info
ここまでの手順で、ローカル環境の **Ubuntu** にアプリの**カスタムコンテナイメージ**をビルドすることができました。
:::

### プロジェクトフォルダに移動

プロジェクトフォルダに移動します。  
※ ~/tmp/BlazorApp をプロジェクトフォルダとします。

```sh
$ cd ~/tmp/BlazorApp
```

### コンテナイメージの確認

Docker デーモンを起動します。

```sh
$ sudo service docker start
 * Starting Docker: docker      [ OK ]
```

:::note warn
Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。
:::

https://qiita.com/studio_meowtoon/items/3bceee25ac67cc73ebbe

コンテナイメージを確認します。

```sh
$ 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 Hub にコンテナイメージを登録  

Docker Hub のアカウントを作成します。  

https://hub.docker.com/signup

Docker Hub にログインします。  

```sh
$ docker login
Login Succeeded
```

コンテナイメージにタグを付けます。

:::note alert
ここで **$USER** という埋め込み変数は、**Ubuntu** のシェル変数 **USER** のことです。つまり、カスタムコンテナイメージを **Docker Hub** にプッシュする際に指定する**アカウント名**と、**Ubuntu** の**ユーザー名**を同じにすると、イメージの取り扱いが簡単になります。ただし、この方法は検証用途に限定されます。
:::

```sh
$ docker tag app-hello-blazor-wasm:latest $USER/app-hello-blazor-wasm:latest
```

Docker Hub にコンテナイメージをプュシュします。

```sh
$ docker push $USER/app-hello-blazor-wasm:latest
```

:::note info
ここまでの作業で、**Docker Hub** に $USER/app-hello-blazor-wasm:latest として**カスタムコンテナイメージ**を公開できました。  
:::

### シェル変数の作成

:::note alert
**シェル変数**として、**Ubuntu** に以下の値を作成します。状況により、コンテナ アプリの名前を変える必要があります。
:::

```sh
$ location_name=japaneast
$ resource_group_name=rg-hello
$ containerapp_env_name=cae-hello
$ containerapp_name=ca-hello-blazor-wasm
$ container_image_name=app-hello-blazor-wasm:latest
```

### Azure 環境にサインイン

こちらの関連記事で手順がご確認いただけます。

https://qiita.com/studio_meowtoon/items/9721041f9e6e3e987cf0

Azure CLI でログインします。  

```sh
$ az login
```

### Azure 環境

#### リソースグループ

リソースグループを作成します。

```sh:Microsoft.Resources/resourceGroups
$ az group create \
    --name $resource_group_name \
    --location $location_name
```

#### コンテナ アプリ環境

拡張機能をインストールします。  
※ 初回のみ必要となります。  

<details>
<summary>手順を表示します。</summary>

##### 拡張機能

拡張機能をインストールします。  

```sh
$ az extension add --name containerapp --upgrade
```

Microsoft.App 名前空間を登録します。  

```sh
$ az provider register --namespace Microsoft.App
```

Microsoft.OperationalInsights プロバイダーを登録します。  

```sh
$ az provider register --namespace Microsoft.OperationalInsights
```

</details>

コンテナ アプリ環境を作成します。    
※ Kubernetes 基盤の環境がベースとなっているので少し時間がかかります。  

```sh:Microsoft.App/managedEnvironments
$ az containerapp env create \
    --resource-group $resource_group_name \
    --name $containerapp_env_name \
    --location $location_name
```

#### コンテナ アプリ

コンテナ アプリの作成とデプロイを行います。    
※ $USER の部分はご自身のコンテナリポジトリに読み替えて下さい。  

```sh:Microsoft.App/containerApps
$ az containerapp create \
    --resource-group $resource_group_name \
    --environment $containerapp_env_name \
    --name $containerapp_name \
    --image $USER/$container_image_name \
    --target-port 80 \
    --ingress 'external' \
    --min-replicas 1
```

#### Azure Portal の確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/d3d745d0-ee89-960f-3888-84f7ff199137.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/510aa057-a73b-a8bb-b6d3-dca1741b4d18.png)

:::note info
ここまでの手順で、**Azure** に**必要なリソース**と、**コンテナ アプリ**が作成されたことが確認できました。
:::

### コンテナ動作の確認

コンテナ アプリの FQDN を Ubuntu のシェル変数 **containerapp_fqdn** に取得します。

```sh
$ containerapp_fqdn=$(az containerapp show \
    --resource-group $resource_group_name \
    --name $containerapp_name \
    --query 'properties.configuration.ingress.fqdn' \
    --output tsv)
```
 
コマンドから Web ブラウザを立ち上げます。(※ WSL Ubuntu)

```sh
$ sudo apt update
$ sudo apt install wslu
$ wslview https://$containerapp_fqdn/
```

<details>
<summary>Ubuntu の Web ブラウザを使う場合</summary>

```sh
$ sudo apt update
$ sudo apt install xdg-utils
$ xdg-open https://$containerapp_fqdn/
```
</details>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/ca803826-f294-3a17-2180-a928f0ea4f10.png)

:::note info
Web ブラウザに **Hello World!"** と表示されました。 
::: 

:::note warn
また **WebAssembly** は W3C 標準仕様なので、拡張機能やプラグイン等を必要とせず、**スマホ**の **Web ブラウザ**でも動作します。
:::

![blazor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/16f9ffb3-ae2b-b3ec-61c7-ef5f20d59db6.png)
### コンテナに接続

コンテナ アプリに接続します。

```sh
$ az containerapp exec \
    --resource-group $resource_group_name \
    --name $containerapp_name
```

コンテナに接続後にディレクトリを確認します。 
※ コンテナから出るときは ctrl + D を押します。  

```
# pwd
/usr/share/nginx/html
# ls -lah
total 28K
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
```

top コマンドで状況を確認します。

```
# top
Mem: 9253672K used, 7139568K free, 4312K shrd, 374016K buff, 6364636K cached
CPU0:   3% usr   1% sys   0% nic  95% idle   0% io   0% irq   0% sirq
CPU1:   2% usr   2% sys   0% nic  95% idle   0% io   0% irq   0% sirq
CPU2:   2% usr   1% sys   0% nic  95% idle   0% io   0% irq   0% sirq
CPU3:   2% usr   1% sys   0% nic  95% idle   0% io   0% irq   0% sirq
Load average: 0.14 0.22 0.26 3/1083 39
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
   30     1 nginx    S     7812   0%   0   0% nginx: worker process
    1     0 root     S     7572   0%   3   0% nginx: master process nginx -g daemon off;
   31     0 root     S     1688   0%   3   0% sh
   39    31 root     R     1620   0%   0   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"
```

:::note warn
このコンテナは Alpine Linux をベースに作成されています。つまり、Alpine Linux と同じように扱うことができます。
:::

## まとめ

Azure Container Apps 環境で、Dockerfile からビルドした C# ASP.NET Core Blazor Web アプリのカスタムコンテナイメージを起動することができました。

:::note warn
**.NET SDK**、**Docker**、**Azure CLI** を使って、ASP.NET Core アプリの開発からコンテナイメージの作成、Azure 環境へのデプロイまで、**すべてをターミナルから行うことができます**。このように、クラウドでのシステム開発に必要なスキルや理解を深めることができます。初めての人でも簡単に手順を追うことができるので、ぜひ挑戦してみてください。
:::

どうでしたか？ 検証目的として、WSL Ubuntu で、C# ASP.NET Core Blazor Web アプリケーションを Azure Container Apps 環境でコンテナとして手軽に起動することができます。ぜひお試しください。今後も Azure の開発環境などを紹介していきますので、ぜひお楽しみにしてください。