Intel MacでもM1 Macでも使えるDockerイメージを作りたい(Docker hubに登録編)
経緯
割とmysql:5.7系使い倒しているところ、まだまだ多いですよね。
そして、そろそろ仕事用の端末としてM1 Macも普及し始めてますよね。
みなさん、M1 Mac上でMySQL立ち上げる時、どうしてますか?
公式だとarm対応はない。
MySQL v8系だと、mysql:8ではなく、mysql-server:8とか、別の回避策が無いわけではないけれど
v5.7系だとちょっと回避が難しい。
そして、完全に全員M1 Macに切り替えられるのであれば、取れる回避策もあるけれど
Intel Macとの共存もしたい。
となると、難易度がとても上がってきます。
そこで
もう探すのは諦めて
自分で作りませんか?
という話です。
大まかな手順
- Dockerfileを作成
- Dockerfileの中でmysqlをコンパイルする処理を書く
- コンパイルする部分以外は極力Docker hubで公式に配られているmysqlのDockerfileに寄せる
- DockerイメージをIntel Mac(x86_64)とM1 Mac(arm64)両方作成してDocker hubにプッシュする
成果物
https://github.com/gendosu/docker-mysql
手順
Dockerfileを作成
ここから、5.7のDockerfile、docker-entrypoint.shを持ってくる
Dockerfileの中でmysqlをコンパイルする処理を書く
元はDebianになっているけれど、Debianはarm版のバージョンが低くて使えないので
ubuntuに変更します。
また、mysqlのコンパイルに、Ubuntuのv22.04だとライブラリのバージョンが違いすぎて
コンパイルがうまく終わらなかったので、v20.04を指定。
詳しい内容はhttps://github.com/gendosu/docker-mysqlを参照してください。
そして、普通にビルドが通ることを確認する
docker build -t example/mysql:5.7.31 .
※exampleのところは自分のDocker Hubのアカウント
DockerイメージをIntel Mac(x86_64)とM1 Mac(arm64)両方作成してDocker hubにプッシュする
ここで使用する物
Docker Desktop(mac)
使用する機能がbuildx
buildxとは?
[gendosu@gens-M1Max ]$ docker buildx --help
Usage: docker buildx [OPTIONS] COMMAND
Extended build capabilities with BuildKit
Options:
--builder string Override the configured builder instance
Management Commands:
imagetools Commands to work on images in registry
Commands:
bake Build from a file
build Start a build
create Create a new builder instance
du Disk usage
inspect Inspect current builder instance
ls List builder instances
prune Remove build cache
rm Remove a builder instance
stop Stop builder instance
use Set the current builder instance
version Show buildx version information
Run 'docker buildx COMMAND --help' for more information on a command.
Usage of buildx:
--builder string
BuildKitによる拡張ビルド機能、という事で、なるほど?よくわからないですね。
普段 docker build を使うと、Docker Desktopとしてインストールされているdockerを使って、そこでビルドをする事になります。
他のプラットフォーム向けのビルドはこの環境では出来ません。
それに対して、buildxで使う環境というのは、BuildKitという、Docker Desktopとしてインストールされている環境ではなくて
別にビルドするための専用の環境を作成して、その中でビルドを走らせましょうというツールになります。
BuildKitを使用したビルドを行うには、ビルダーという環境を作るところから始める必要があります。
という事で、環境を作ります。
まずは確認
docker buildx ls
[gendosu@gens-M1Max ]$ docker buildx ls
default * docker
default default running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
defaultというのがありますが、これとは別にBuildKitを使ったビルドが出来る環境を作ります。
docker buildx create mybuilder
[gendosu@gens-M1Max ]$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
mybuilder docker-container
mybuilder0 desktop-linux inactive
default * docker
default default running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
DRIVERがdocker-containerになっているmybuilderレコードが作成されていると思います。
docker上でコンテナを起動して、その中で複数環境のビルドをする、という感じかと思います。
で、デフォルトでmybuilderを使用するように設定
docker buildx use mybuilder
[gendosu@gens-M1Max ]$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
mybuilder * docker-container
mybuilder0 desktop-linux inactive
default docker
default default running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
BuildKitの準備が出来ました。
続いて、ビルド&プッシュ
docker buildx build -t example/mysql:5.7.31 --platform linux/amd64,linux/arm64 --push .
ここで使うbuildコマンドは
docker buildとほぼ同等ですが、docker buildにはないオプションがいくつかあります。
docker buildx build
で追加されている主なオプションが
—platform
プラットフォームを指定出来ます。linux/arm64
linux/amd64
などをカンマ区切りで指定します。
—push
通常、自身のプラットフォームに合わないイメージは持てないので、ビルドした結果を保持出来ません。
なので、buildxでビルドした結果を直接Docker hubにプッシュしてしまおう、というオプションになります。
注意点
注意点1
Dockerfile内部で、プラットフォーム依存な処理を書いてしまうと
ビルド時にエラーになってしまいます。
どちらの環境でも問題なく処理できる実装をする必要があります。
注意点2
M1 Macであっても、amd64(x86_64)のMySQLのDockerイメージを作成する部分がとても遅いです。