つい先日、我が家にM1 Macが届きました。
「Dockerまわりがつらいよ」という話は聞いていましたが、私もしっかりと MySQL のコンテナが立ち上がりませんでした。
軽くググっても「むむ・・・?🤔」と思う結果だったので、自分でしっかりまとめてみようと思います。
そもそもの問題
M1 Mac で Docker 公式の MySQL コンテナをそのまま使おうとすると、以下のエラーが出て使用できません。
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries
これは雑に説明すると、「このコンテナは ARM64 に対応してないよ」ということです。
そして、 M1 チップは ARM64 アーキテクチャを採用しています。
解決する方法
色々と調べてみると、主に3つの方法があるようです。
arm64v8/mysql
イメージを使用するmysql/mysql-server
イメージを使用する--platform linux/amd64
オプションを使用する
順番に見ていきましょう。
MySQLのみを使いたいなら arm64v8/mysql
Docker の公式リポジトリに、 AMD64 (Intel の CPU のアーキテクチャ) 以外のプラットフォームの案内があります。
それによると、
Some images have been ported for other architectures, and many of these are officially supported (to various degrees).
とあり、程度差はありますが、公式にサポートされているイメージがあることがわかります。
そして、その MySQL のイメージが arm64v8/mysql
です。
使い方は公式の MySQL イメージとほぼ同じなので、イメージを書き換えるだけで使用できます。
チーム開発をしていて、 Intel CPU の人と M1 チップの人の両方がいる場合、 docker-compose.override.yml
を使用すると便利です。
# docker-compose.yml version: '3' services: mysql: # デフォルトでは mysql イメージを使う image: 'mysql:8.0' ports: - '${FORWARD_DB_PORT:-3306}:3306' environment: MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' MYSQL_DATABASE: '${DB_DATABASE}' MYSQL_PASSWORD: '${DB_PASSWORD}' MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' volumes: - 'sailmysql:/var/lib/mysql' networks: - sail healthcheck: test: ["CMD", "mysqladmin", "ping"] some_other_containers: ...
# docker-compose.override.yml version: "3" services: mysql: # M1 チップの人は arm64v8/mysql で上書きする image: 'arm64v8/mysql:8.0-oracle'
一方で、 mysql はOSの選択肢が debian
と oracle
があるのに対し、 arm64v8/mysql は oracle
しかありません。
なので、 監視ツールなどで Debian でしか動かないツールを使いたい場合には使用できません。
また、本番は Debian のコンテナで動いていて、なるべく本番に近い環境で開発したい場合も向きません。
設定ファイル差異をなくすなら mysql/mysql-server
Docker 公式のイメージは ARM64 をサポートしていませんが、 MySQL 公式のイメージは ARM64 をサポートしています。
MySQL 公式のイメージが mysql/mysql-server
です。
このイメージを使用すれば、M1 チップでも (docker-compose.override.yml
を書かずとも) 同じ docker-compose.yml
で動かすことができます。
一方で、 Docker 公式のイメージではないため、 MYSQL_PASSWORD
のような環境変数による初回設定には対応していないようです。
そのため、既存で Docker 公式のイメージを使用しており、環境変数による初回設定を行っている場合は、mysql/mysql-server
へのマイグレーションはコストがかかりそうです。
MySQL コンテナをカスタマイズしてるなら --platform linux/amd64
MySQL コンテナで MySQL 以外のミドルウェアをインストールしていたり、込み入った設定をしていたりなど、他イメージに移行することが難しい場合があります。
その際に有効なのが --platform linux/amd64
オプションです。
Docker for Mac の公式ページに、以下のように書かれています。
Not all images are available for ARM64 architecture. You can add --platform linux/amd64 to run an Intel image under emulation. In particular, the mysql image is not available for ARM64. You can work around this issue by using a mariadb image.
雑に和訳すると、「全部のイメージが ARM64 で動くわけじゃないよ。 --platform linux/amd64
オプションを付ければ Intel イメージをエミュレーション上で動かすことができるよ。特に mysql イメージは ARM64 じゃ動かないよ。 mariadb のイメージを使って解決することもできるよ。」
といった感じでしょうか。
docker-compose.yml
を使用する場合は、以下のように書くといけます。
# docker-compose.yml version: '3' services: mysql: image: 'mysql:8.0' platform: 'linux/amd64'
ひとつ気になることがあります。
docker-compose file v3 では、ドキュメントから platform
オプションが消えています。 (v2 にはあります。)
ですが、リリースノートを見ても「 platform
オプションを消した」という記述は見当たりません。
現状サポートされているのか、 非推奨な機能なのかわからない状態です。
ところで、このオプションを指定するとエミュレーション上で動作するということが重要です。エミュレーションをするということは、以下のことを指します。
- エミュレータがエラーを起こす場合がある
- エミュレータを挟むので、いくつかの Docker の機能が使用できなくなる
- エミュレータ上で動作させるので、速度が遅くなる
- エミュレータ上で動作させるので、メモリ消費が激しい
なので、 --platform linux/amd64
オプションを使用するのは、最終手段にすることをおすすめします。