🐳

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とは?

https://github.com/docker/buildx

  • Docker Desktopの拡張プラグイン
  • builder = イメージを作る専用の仮想空間
  • BuildKitというソフトウェアが肝で、CPUの違いを吸収してビルドしてくれる
  • buildxを通して、builderを操作する
  • builderは複数作成できる
  • 作成したbuilderでプラットフォームを選択してビルドする
    • 一旦は「MacOSでLinux環境で動くコンテナのイメージを作れる」という認識で良さそう

図にしてみました

まとめると以下の感じかと思います。

builderの概念図

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です。

builderの概念図

おまけ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の違いもいつか記事にしたい...)

認識違いありましたらご指摘いただけると幸いです。

最後までお読みいただきありがとうございました。

参考

https://zenn.dev/bells17/articles/docker-buildx

https://qiita.com/Tomato_otamoT/items/e808eb7f959c5942eaf6

Discussion