【docker】M1 Macでdockerのmysqlが爆死するけど何故？【mysql】

## はじめに
先日、私自身が経験したことではあるのですが
1. Intel Mac で元々``mysql5.7-debian``のイメージを使って業務をしていた
2. （諸事情で）一時的にM1 Macを使わねばならなくなり、同じdockerfileを使って環境を作ろうとした
3. **爆死した。**

はて…dockerってローカルの環境差を埋めて、誰でも彼でも同じ環境で開発ができる素敵クジラちゃんじゃないのか？
解決策はググれば結構転がっているのだけど、何故そうなるのかよく分からなかったのでちょっと探求してみました。


## とりあえず、爆死しがちなパターンとその解決策
なんかの間違いで``docker mac m1``でググってここにたどり着いてしまった方に申し訳ないので
とりあえず、爆死パターンと解決策。（を転記）
爆死しがちなのは、利用者もきっと多い``mysql 5.x系``ですね。5.6とか5.7とか。
私が今回爆死したのも上述の通り``mysql 5.7-debian``です。

で、爆死するときはこんな感じ。（M1 Macは手放したので、参照記事からまんまぶっこ抜かせてもらいました。）
```vim:mysql 5.6のimageを使ってM1 Macでビルドしようとした
$ docker-compose up -d --build

〜略〜

 => ERROR [internal] load metadata for docker.io/library/mysql:5.6                                                                                                                                                                                                         2.4s
------
 > [internal] load metadata for docker.io/library/mysql:5.6:
------
failed to solve with frontend dockerfile.v0: failed to create LLB definition: no match for platform in manifest sha256:~~~~~~ not found
ERROR: Service 'db' failed to build : Build failed
```

解決策としては色々あるのですが、私自身これでいけましたっていうのが
``platform: linux/amd64`` ってオプションを差してあげること。

```yml:docker-compse.yml mysqlだけ
# ##### mysql #####
    mysql:
        image: mysql:5.7
        platform: linux/amd64 #これを入れるだけで何とかなったりする
        build:
            context: . 
            dockerfile: ./docker/mysql/Dockerfile
        container_name: foo_project_mysql
        environment:
            - MYSQL_ROOT_PASSWORD=root
            - MYSQL_DATABASE=foo
            - MYSQL_USER=bar
            - MYSQL_PASSWORD=hogefuga1111
            - TZ=Asia/Tokyo
```

これを差せば大丈夫っていう理由がよく分かりません。

## CPU アーキテクチャとDocker Image
そもそも、この``platformオプション``は何を指しているのか。``linux/amd64``って何よ？についてもう少し。

#### linux/amd64 って何よ？
**CPUアーキテクチャ** のことを指すようです。
ここでいうアーキテクチャは、**命令セットアーキテクチャ（Instruction Set Archtecrure）** のことを指し、CPUに命令する機械語の仕様を定めたものです。

**amd64** ってのはそのアーキテクチャの一種（通称）で、Intel Macはこのamd64というアーキテクチャのCPUが乗っています。（厳密に言ってしまうと色々語弊があるっぽいですが``amd64 = intelのCPU``というイメージで大体OK）

じゃあM1 Macはどうなのかというと、**arm64**という、ほとんどのスマホやタブレットで使用されている米ARM社仕様のCPUが乗っています。
そのため、Intel Mac とM1 Macとでは、そもそもマシンを動かす機械語の仕様レベルで異なるわけです。
~~こういう俺様仕様なところ、本当appleって気持ち悪いから嫌い。Lightning端子とか早々に滅びろ。~~

#### dockerのマルチアーキテクチャサポート機能
dockerでは、イメージをpullしてくるときに、**マシンのOSに対応するイメージを選択してpullしてくれる機能**が備わっています。本筋のLinuxはもちろん、mac / windowsなど様々なCPUやOSでの利用者を想定してのことでしょう。たぶん。

たとえばこんなん。
![mysql8.0](https://i.gyazo.com/18e7bd3bb620b25d51cabf02b3b63951.png)
**linux/amd64** と **linux/arm64** の２種があります。
普段はまったく意識しないと思いますが、docker側でOSやアーキテクチャを判定してその環境に合ったイメージをpullしてくれます。

さて問題の``mysql5.7``はどうでしょう。
![mysql5.7](https://i.gyazo.com/c0d3a12b90733831453c0b6db198c109.png)
amd64（Intel系）しかありません。残念です。

#### M1 Macでmysql5.7が爆死する理由
ここまでのことを踏まえると、M1 Macにmysql5.7のイメージをpullしようとするとエラーが出る原因は

1. M1 / Intel ではそもそもCPUアーキテクチャが違うので、根本的にマシンの動かし方が違う
1. dockerでは、マルチアーキテクチャサポート機能により、マシンに合わせて自動でイメージをpullしようとする
1. しかし、mysql5.7にはarm64用のイメージが存在しないため、うわぁぁぁぁ！！！！ってなる
1. **爆死する。**

というように考えられそうです。

#### お待たせしましたplatformオプション
もう大体お察しと思いますが、``platformオプション``は**pullしてくるイメージのアーキテクチャを指定する**オプションです。
なので、M1環境ではあれどamd64用（しかないから仕方なく）のイメージをpullしてねとdocker-compose.ymlに記載してあげることで何とか環境が立ち上がるということのようです。

```yml:docker-compse.yml 再掲
# ##### mysql #####
    mysql:
        image: mysql:5.7
        platform: linux/amd64 # M1=amd64環境だけど、amd64用のイメージをpullするぜ！を指定。
        build:
            context: . 
            dockerfile: ./docker/mysql/Dockerfile
        container_name: foo_project_mysql
        environment:
            - MYSQL_ROOT_PASSWORD=root
            - MYSQL_DATABASE=foo
            - MYSQL_USER=bar
            - MYSQL_PASSWORD=hogefuga1111
            - TZ=Asia/Tokyo
```

## ちなみに。
マシンのアーキテクチャとdockerイメージのアーキテクチャが異なっている（今回の場合amd64 と arm64）のに問題なく動くの？という疑問が残りますが、ここはdocker側の方でよしなに動くようにしてくれているようです。
（ソースを見つけることができませんでしたホントすみません）

以前は、QEMUなどのエミュレータを入れてあげる必要があったようですが。


## 参考リンク
https://docs.docker.jp/docker-for-mac/multi-arch.html

https://zenn.dev/suzuki_hoge/books/2021-07-m1-mac-4ede8ceb81e13aef10cf

https://e-words.jp/w/%E5%91%BD%E4%BB%A4%E3%82%BB%E3%83%83%E3%83%88.html

https://qiita.com/ryamate/items/3c48798cf33dc443ae22

https://zenn.dev/tetsu_koba/articles/b9545eb0231d7e