Docker buildxの基礎知識:ビルド専用コンテナ「builder」の概念と操作コマンド
背景
- 1, M3チップPCでビルドしたイメージをpushしてCloud Runにデプロイしたが、エラー。
- 2, gcloud CLIで返ってきたエラーメッセージが、「PORT 8080が設定されてませんよー」とか「タイムアウトを延長してね」とか全っ然違うこと言っていて、ハマった。
- 3, Cloud Loggingを見たら「textPayload: "terminated: Application failed to start: failed to load /usr/local/bin/python3: exec format error"」とあった。
-
exec format errorというのが典型的なCPUアーキテクチャ不一致のエラーらしい。 - マルチプラットフォームでのビルドが必要な様子(x86_64に対応していればとりあえずいい)
-
課題の解決にDocker buildxが使えるらしいことを知ったので、概念とできることをまとめます。
Docker buildxとは?
- Docker Desktopの拡張プラグイン
- builder = イメージを作る専用の仮想空間
- BuildKitというソフトウェアが肝で、CPUの違いを吸収してビルドしてくれる
- buildxを通して、builderを操作する
- builderは複数作成できる
- 作成したbuilderでプラットフォームを選択してビルドする
- 一旦は「MacOSでLinux環境で動くコンテナのイメージを作れる」という認識で良さそう
図にしてみました
まとめると以下の感じかと思います。

builderはアプリケーション用コンテナとは「用途が違うDockerコンテナ」と表現できそうです。
イメージをビルドするためのコンテナですので。
操作
MacOSでbuildxでビルド→CloudRunデプロイで操作した手順は以下です。(イメージ名は仮です)
前提: Docker Desktopがインストールされ起動していること
新しい builder 作成
docker buildx create --name mybuilder --use
使うbuilderを選択
docker buildx use mybuilder
builder一覧
docker buildx ls
#=> 出力例(defaultとdesktop-linuxは削除不要。)
>>> docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
mybuilder* docker-container
\_ mybuilder0 \_ desktop-linux inactive
default docker
\_ default \_ default running v0.17.3 linux/amd64 (+2), linux/arm64, linux/arm (+2), linux/ppc64le, (3 more)
desktop-linux docker
\_ desktop-linux \_ desktop-linux running v0.17.3 linux/amd64 (+2), linux/arm64, linux/arm (+2), linux/ppc64le, (3 more)
選択し * がついたmybuilderを見ると、まだinactiveなので、以下でrunnningにする。
builder有効化
docker buildx inspect mybuilder --bootstrap
再度lsをして、runnningになっていることを確認。
(調べたところdocker buildx create --name mybuilder --use --bootstrapで作成と有効化同時も可能でした。)
単一プラットフォーム向けビルド
今回はデプロイ先のCloudRunのCPUに合わせてx86_64(amd64)でビルドをしたいので、以下。
docker buildx build --platform linux/amd64 -t myimage:amd64 .
x86_64(amd64)専用イメージができました。
この後gcloud run deployコマンドを実行し、無事Cloud Runにデプロイできました!🎉
なお、ARM64専用イメージは以下でできるとのこと。
(Windows/Linuxでarm向けを作成...あんまり考えにくいですが)
docker buildx build --platform linux/arm64 -t myimage:arm64 .
おまけ
(参考)マルチプラットフォーム向けビルド
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myimage:latest \
.
builder を停止
docker buildx stop <<builder名>>
builder を削除
docker buildx rm <<builder名>>
コマンドを見ると慣れ親しんでいるdockerやcomposeコマンドと同じような感覚で使えることがお分かりいただけると思います。
再掲しますが、用途の違うビルド用のDockerコンテナがbuilderで、それをCLIで操作するのがbuildxです。

おまけ2
ちなみにdocker psでrunningのbuilderも見れます。
アプリコンテナと混ぜて見られるのが面白いですね!
docker ps
#=> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
268c373111b8 moby/buildkit:buildx-stable-1 "buildkitd" 19 minutes ago Up 19 minutes buildx_buildkit_mybuildera0
(微小ながらリソース食うので不要ならbuilder止めておきましょう)
終わりに
buildxを使うことで、「MacOSで開発しCloudRunにデプロイ」が実現できました。
参考記事曰くbuildxでのハマりポイントも色々あるらしいです。興味あれば読んでみたい。
(armとamdの違いもいつか記事にしたい...)
認識違いありましたらご指摘いただけると幸いです。
最後までお読みいただきありがとうございました。
参考
Discussion