Cross/multi-platform build for Docker
手元で試した感じたしかに速くなっている。
Before: 1m 12s
After: 31s
以下のQEMUのセットアップを忘れていたので、この結果が正しいものかはあやしいな…。
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
docker/build-push-action@v6
の出力を見ると次の変化があった。
#12 [linux/amd64->arm64 builder 2/6] WORKDIR /usr/src/app
#12 DONE 0.4s
プラットフォームをamd64で固定したbuilderステージでは、linux/amd64->arm64
となっていた。
ターゲットのプラットフォームとビルドプラットフォームが異なることがわかるログの出方をしている。
GitHub Actions と連携してやる場合。
チュートリアルはここに載っている。
テンプレートとして紹介されているclockbox
はこれ。
Dockerfile1つだけのシンプルなリポジトリ。
docker/build-push-action@v6
アクションに以下を足すことでプラットフォームが指定可能になる。
platforms: linux/amd64,linux/arm64
1つのrunner内で2つのプラットフォームのビルドが並行で走っているように見える。
次は出力の抜粋。
#4 [linux/amd64 internal] load metadata for docker.io/library/golang:1.22-alpine
#4 DONE 1.1s
#5 [linux/arm64 internal] load metadata for docker.io/library/golang:1.22-alpine
#5 DONE 1.1s
#6 [linux/amd64 internal] load metadata for docker.io/library/alpine:latest
#6 DONE 1.1s
#7 [linux/arm64 internal] load metadata for docker.io/library/alpine:latest
#7 DONE 1.1s
最後のほうにマニフェストが作れられてそれもpushされている。
#26 exporting to image
#26 exporting layers 0.1s done
#26 exporting manifest sha256:f642e371e1ad43b8367aa43fcc06d79986a1d2d0dc667326a65a60cf37d65868 done
#26 exporting config sha256:5f7608ccbe26ba59c14842fdca7f9c7b32c44d207d06f35373f7d133914120cc done
#26 exporting attestation manifest sha256:df6f2e9cf709d2ac65e36b820ef21de7d2de1b6eb16af27fecc8478b98dbf5ec done
#26 exporting manifest sha256:2341871ab41c137fdbef2f5e3747893c9ae42c88ddbb0b99f195a4fe74ce60e1 done
#26 exporting config sha256:12f06cd22b3c2c094b1f7ce08490c78ef577c5acef9aaacf23f2c25ec1c34386 done
#26 exporting attestation manifest sha256:889d106efa97797e951ea4bc494825d8fb5b12f07c7bc2dab81a6cbbff0ae26a done
#26 exporting manifest list sha256:9677db7ab12a8fecab6b07b4a41edc57877ff522d132782c6ec57c3fafb2a16d done
#26 pushing layers
#26 ...
#27 [auth] bellwood4486/sample-go:pull,push token for registry-1.docker.io
#27 DONE 0.0s
#26 exporting to image
#26 pushing layers 1.3s done
#26 pushing manifest for docker.io/bellwood4486/sample-go:gh@sha256:9677db7ab12a8fecab6b07b4a41edc57877ff522d132782c6ec57c3fafb2a16d
#26 pushing manifest for docker.io/bellwood4486/sample-go:gh@sha256:9677db7ab12a8fecab6b07b4a41edc57877ff522d132782c6ec57c3fafb2a16d 0.8s done
#26 DONE 2.4s
マルチプラットフォームのイメージとして作られた。
マルチプラットフォームの場合はINDEX DIGEST
となっている。
INDEX DIGEST sha256:9677db7ab1...
(非マルチの場合はここがMANIFEST DIGEST
)
マニフェストの情報がコマンドから確認できる。
❯ docker buildx imagetools inspect bellwood4486/sample-go:gh
Name: docker.io/bellwood4486/sample-go:gh
MediaType: application/vnd.oci.image.index.v1+json
Digest: sha256:596676a7b2cf7114cbefa91728520e116cf7341edef5c569c6c7c6e7e6cbeae6
Manifests:
Name: docker.io/bellwood4486/sample-go:gh@sha256:0935257799f8e4974e55ffc226e6f04acfcb9cfac6bdf522bfe3327a13cc1a92
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: linux/amd64
Name: docker.io/bellwood4486/sample-go:gh@sha256:ae4b6590554821ff4d1171ccf999b2a5a4f3b5db1c2618502e764f26606d31db
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: linux/arm64
Name: docker.io/bellwood4486/sample-go:gh@sha256:2fb74abc811c6063b3ff224d39fac28e2a65b6c57050cbf66d35a6abacd599a0
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: unknown/unknown
Annotations:
vnd.docker.reference.digest: sha256:0935257799f8e4974e55ffc226e6f04acfcb9cfac6bdf522bfe3327a13cc1a92
vnd.docker.reference.type: attestation-manifest
Name: docker.io/bellwood4486/sample-go:gh@sha256:79681852ad6d29abb2fda4accfbeade8beb0db791845d3be6eba490872ea638d
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: unknown/unknown
Annotations:
vnd.docker.reference.digest: sha256:ae4b6590554821ff4d1171ccf999b2a5a4f3b5db1c2618502e764f26606d31db
vnd.docker.reference.type: attestation-manifest
docker コマンドのみでやる場合。一番シンプルな構成。
初期設定のままやってみると次のエラーになる。
❯ docker build -t bellwood4486/sample-go:cli --platform linux/amd64,linux/arm64 .
[+] Building 0.0s (0/0) docker:desktop-linux
ERROR: Multi-platform build is not supported for the docker driver.
Switch to a different driver, or turn on the containerd image store, and try again.
Learn more at https://docs.docker.com/go/build-multi-platform/
By default, Docker can build for only one platform at a time. To build for multiple platforms concurrently, you can:
Enable the containerd image store: The default image store in Docker Engine doesn't support multi-platform images. The containerd image store does, and lets you create multi-platform images using the default builder. Refer to the containerd in Docker Desktop documentation.
Create a custom builder: Initialize a builder that uses the docker-container driver, which supports multi-platform builds. For more details, see the docker-container driver documentation.
デフォルトでは指定できるプラットフォームは1つのみ。
- containerd image store を有効にする
- カスタムビルダーを作る
をしないといけないらしい。
containerd image store の説明はここに書いてある。
いったん中断して、GitHub Actions を使う方を試してみる。
Goを例としてDockerfileの書き方なども載っている。
Emulationのイメージがわかりやすい。