docker-composeでのMySQL環境構築(M1 Mac対応版)
はじめに
以前、docker-composeでMySQLのサーバーを建てる記事を書きました。
しかし、これはM1 Macでは動作しません。今回はM1 Mac/Intel Macの両方で動作するようなdocker-compose.ymlに修正していきます。
まずはエラーの確認
M1 Macで以前の記事のコードを実行してみます(MySQLのバージョンだけ最新に変えてます)。
FROM mysql:8.0.28 RUN apt-get update && \ apt-get install -y tzdata locales && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ locale-gen ENV LANG en_US.UTF-8 CMD ["mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
version: '3.8' services: db: build: ./docker/mysql env_file: - .env ports: - "${MYSQL_PORT}:3306" volumes: - ./docker/mysql/data:/var/lib/mysql
$ docker compose build [+] Building 0.9s (3/3) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 32B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => ERROR [internal] load metadata for docker.io/library/mysql:8.0.28 0.8s ------ > [internal] load metadata for docker.io/library/mysql:8.0.28: ------ failed to solve: failed to solve with frontend dockerfile.v0: failed to create LLB definition: no match for platform in manifest sha256:fc77d54cacef90ad3d75964837fad0f2a9a368b69e7d799665a3f4e90e600c2d: not found
ぱっと見て何がいけないのかわかりにくいので、docker runでミニマムに実行してみます。
$ docker run -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.28 Unable to find image 'mysql:8.0.28' locally 8.0.28: Pulling from library/mysql docker: no matching manifest for linux/arm64/v8 in the manifest list entries. See 'docker run --help'.
no matching manifest for linux/arm64/v8 in the manifest list entries.
とあるので、arm64/v8用のイメージが存在しないことによるエラーであるとわかります。
公式イメージをM1 Macで動かす
FROMのオプションに --platform=linux/x86_64
をつけることで、x86_64環境用のイメージを使います。
--- a/docker/mysql/Dockerfile +++ b/docker/mysql/Dockerfile @@ -1,4 +1,4 @@ -FROM mysql:8.0.28 +FROM --platform=linux/x86_64 mysql:8.0.28 RUN apt-get update && \ apt-get install -y tzdata locales && \
これで起動できました。
参考にした記事には5.7の場合はLinux Native AIO interfaceのエラーが発生するのでもうひと手間加える必要があると書いてありましたが、今(2022年4月26日) mysql:5.7.37
で試してみたところ普通に動作しました。不思議。
別のイメージを使う
ここまで使ってきた mysql
は Docker 公式のイメージですが、 mysql/mysql-server
というMySQL公式のイメージもあり、こちらは --platform
オプションなしでも動作しました。
こちらはタイムゾーンやロケールも環境変数で変更できるので、 mysql
イメージのときのように Dockerfile でtzdataやlocalesをインストールする必要はありません。これらを変更するだけであればDockerfileを書く必要がないのもメリットですね。
version: '3.8' services: db: image: mysql/mysql-server:5.7.37-1.2.7-server environment: MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}" MYSQL_DATABASE: "${MYSQL_DATABASE}" MYSQL_USER: "${MYSQL_USER}" MYSQL_PASSWORD: "${MYSQL_PASSWORD}" MYSQL_ROOT_HOST: "%" TZ: "Asia/Tokyo" LANG: "en_US.UTF-8" command: [ mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci ] ports: - "${MYSQL_PORT}:3306" volumes: - ./docker/mysql/data:/var/lib/mysql
TZ
でタイムゾーン、 LANG
で言語を設定しています。 MYSQL_ROOT_HOST
はrootに別のコンテナから接続するのに必要な設定です。
特にplatformを指定しなくても、これだけで正常に起動できます(5.7はx86_64しかないようですが、8.0にはarm64用のイメージもありました)。
おわりに
- 公式イメージで
--platform
オプションを使う方法 mysql/mysql-server
を使う方法
の2つを試しました。
MySQL5.7の場合はmysql
も mysql/mysql-server
もx86_64用イメージになるのでどちらでもいいかもしれませんが、MySQL8の場合は mysql/mysql-server
を使うとハードウェアに合ったイメージを使うことができてよさそうです。
個人的には mysql/mysql-server
だと Dockerfile 不要なのが棚ぼた的に嬉しかったのもあり、こちらに乗り換えています。
余談
私がM1 Macを購入した当時はM1でMySQLを使う記事があまり見つからなくて苦労したのですが、気づけば結構増えていますね。