MacでAzureチュートリアルのACRからデプロイを試すとコンテナの再起動ループした

### はじめに
Azureの勉強とコンテナの復習をしようと思い、まずはMicrosoft提供のチュートリアルを軽くやってみよう！
と、コンテナ作成→ACRからデプロイまでのチュートリアルをやってみました。

https://learn.microsoft.com/ja-jp/azure/container-instances/container-instances-tutorial-deploy-app

1時間程度で終わると思っていましたが、再起動ループする問題にハマってしまい、結局5-6時間くらいかかってしまいました笑

「同じ轍を踏んでしまう方が減るように」という思いを込めて、久々に記事を書きます。

### 事象
「M1」Mac上で、Azure公式のチュートリアルにしたがってAzureContainerRegistry(以下、ACR)からコンテナにデプロイをしても、コンテナが再起動ループをしてしまう。

![スクリーンショット 2024-07-22 19.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227407/3233d80d-983d-a7ce-11db-218dd6ca8297.png)
→Azureポータルのコンテナ情報で、「該当コンテナ動作していない可能性があります。」と表示される。
→FQDNからアクセスしても、正常にページが表示されない。

![スクリーンショット 2024-07-22 19.57.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227407/cdb62f0e-664c-b93f-7798-d68e492fb3fc.png)
→Azureポータルのコンテナ情報詳細から、再起動を複数回繰り返していることがわかる。
（キャプチャ撮り忘れましたが、再起動を繰り返しているためログが取れない。）

ローカルでの実行時には正しく動くのに・・・ナゼ😭😭

### 環境
- MacBookAir(M1)
- MacOS:Sonoma(14.4.1)
- AzureCLI:2.62.0
- Docker version 20.10.8

### 結論


**一言で言うと、「Appleシリコンでビルドしたコンテナは要注意」です。**
→お急ぎの方は回避策セクションへ

前提として、コンテナのビルド時には一般的なAMD64プラットフォーム(以下、PF)でビルドされることが期待動作です。
しかし、以下の箇所でPFの不整合が発生します。

1. Appleシリコン環境でビルドすることで、「ARM64」PFでビルドされてしまう。
2. ローカル環境で確認時は、コンテナと実行環境のPFに違いがないため正常に動作する。
3. ACRから標準で作成したコンテナ「AMD64」では、実行環境と異なるPFのビルドのコンテナ「ARM64」が実行される。

→この「ビルドしたコンテナ」と「実行環境」のPF違いが生じることでコンテナが再起動ループする不具合が発生する模様です。

:::note warn
補足
--platform指定を行わない(通常)の場合は、実行環境のPFがデフォルト値です。
(=Appleシリコン上で--platform未指定でビルドした場合はARM64でビルドされる)
::::

:::note info
ARM64とAMD64(x86-64)の整理

今回の問題においては、CPUアーキテクチャについても軽く知識が必要です。
以下サイトが非常にわかりやすいです。
https://developer.a-blogcms.jp/blog/custom/docker-arm64.html

- x86-64:amd64とIntel64のいずれかを採用しているもの
- ARM-64:ARM PFを採用しているもの
:::


### 回避策

#### a.docker build時に--platform指定を行う
→これで十分(基本的には個人環境が起因の可能性が多いと考えられるため)
→個人利用の範囲や、グループ開発で数名がMacを利用している場合
```shell
docker build --platform linux/amd64 [ビルド資材の指定]
```

#### b. Dockerfileに --platform指定を行う
→aの対応では不十分な場合に検討
→グループ開発等で開発環境が異なるメンバーが多い場合等
```Dockerfile:Dockerfile
# 以下のようにamd64をplatformに明示的指定する
FROM --platform=linux/amd64 node:8.9.3-alpine
```

#### c. docker buildをマルチプラットフォームとする
→グループ開発や、大規模な開発等において様々な環境に対応しておきたい場合
→これをやるなら、プロジェクト開発全般のスコープ・ライフサイクルを見据えて対応した方が良い
```shell
docker build --platform=linux/amd64,linux/arm64,linux/s390x [ビルド資材の指定]
```
※マルチPF向けの `docker buildx` というものもあるらしい・・・。気になった方は公式ドキュメント等をご確認ください。 

### (DockerImageのPFを確認したい時)
:::note warn
下記のコマンドはclaude3.5 Sonnetに聞いた結果です。筆者でも動作確認を行い、正しいplatformが出力されています。
::::
`docker image inspect` で確認することができます。

```shell
docker image inspect --format '{{.Os}}/{{.Architecture}}' <image_name or image tag>

# 参考①（Appleシリコンでそのままbuildしたとき）
# docker image inspect --format '{{.Os}}/{{.Architecture}}' aci-tutorial-app  
# linux/arm64

# 参考②（build時に--platform指定したとき）
# docker image inspect --format '{{.Os}}/{{.Architecture}}' eadd1a79dc37
# linux/amd64
```

### おわり

Appleシリコンだと、開発や作業しているときにARM系の問題に遭遇しやすいです。
「手順通りにやっているのに、動かない。」という時には、まずはAppleシリコン特有の問題かどうか確認するようにしましょう。

私の場合、Azure上のログ等も確認したのですが、再起動ループしてしまうためそもそもログが正常に出力されないため原因の特定に時間がかかりました。
そういえば「Appleシリコンが怪しいのでは・・・」と推測→調査して気づいたという結果です。

#### P.S
Microsoft様、MacでAzureを使った開発される方も増えてるので、
注意事項に、「Appleシリコンでコンテナを作成するときはPFに気をつけてね」と
書いてて貰えると、助かるなぁ。
（特に初心者向けチュートリアル系は丁寧にした方がいいのかもと筆者は考えます🙏）