docker buildx で multi-platform image をビルドし build cache と共に ECR に push する
dockermulti-platform image は複数のプラットフォームの manifest のリストである Index を持つイメージ。
$ cat Dockerfile
FROM --platform=$BUILDPLATFORM golang:1.23 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
ARG TARGETOS TARGETARCH
RUN CGO_ENABLED=0 \
GOOS=$TARGETOS \
GOARCH=$TARGETARCH \
go build -o /out/app .
FROM gcr.io/distroless/static-debian12
COPY --from=build /out/app /app
ENTRYPOINT ["/app"]
$ docker buildx build --platform linux/amd64,linux/arm64 \
--tag $ECR_REPOSITORY . \
--push
ECR だと Image と同列に Index が並ぶ。
クライアントはこの Image Index を見て必要な Platform の image を持ってくることができる。attestation は BuildKit によって作られる、どのようにビルドされ何が含まれているかのメタデータ。
$ docker buildx imagetools inspect $ECR_REPOSITORY
Name: *****
MediaType: application/vnd.oci.image.index.v1+json
Digest: sha256:73db34063986922f958fe9aa0dbb9a1962f9298e69b04b07c02e6697ee0fb126
Manifests:
Name: *****@sha256:3486d283af679b5461f4c563861bed46634a3d580d0353ab8a460f4c061e35e8
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: linux/amd64
Name: *****@sha256:8289b5c98cae3d6666f62a75661c7c43c5d9303d3fc0f69a35f414af7cde8a6a
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: linux/arm64
Name: *****@sha256:f309b8f1aec49ea2e93021444d580e723726267a875cc681beac16c0eb4c4dcf
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: unknown/unknown
Annotations:
vnd.docker.reference.digest: sha256:3486d283af679b5461f4c563861bed46634a3d580d0353ab8a460f4c061e35e8
vnd.docker.reference.type: attestation-manifest
Name: *****@sha256:89dd415537cf2b40d4976d2a8363abbb45e720ad689b8315e2b76a7f3cca67b2
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: unknown/unknown
Annotations:
vnd.docker.reference.type: attestation-manifest
vnd.docker.reference.digest: sha256:8289b5c98cae3d6666f62a75661c7c43c5d9303d3fc0f69a35f414af7cde8a6a
CI のような毎回真っ新になる環境では –cache-to type=registry で外部に保存しておいたビルドキャッシュを利用することでビルドを高速化できる。
$ docker buildx build --platform linux/amd64,linux/arm64 \
--cache-from type=registry,ref=$ECR_REPOSITORY:buildcache \
--cache-to type=registry,ref=$ECR_REPOSITORY:buildcache \
--tag $ECR_REPOSITORY . --push
$ docker buildx prune -a -f
$ docker buildx build --platform linux/amd64,linux/arm64 \
--cache-from type=registry,ref=$ECR_REPOSITORY:buildcache \
--cache-to type=registry,ref=$ECR_REPOSITORY:buildcache \
--tag $ECR_REPOSITORY . --push
=> CACHED [linux/arm64 build 2/6] WORKDIR /src 0.0s
=> CACHED [linux/arm64 build 3/6] COPY go.mod go.sum ./ 0.0s
=> CACHED [linux/arm64 build 4/6] RUN go mod download 0.0s
=> CACHED [linux/arm64 build 5/6] COPY . . 0.0s
=> CACHED [linux/arm64 build 6/6] RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o /out/app . 0.0s
=> CACHED [linux/arm64 stage-1 2/2] COPY --from=build /out/app /app 0.0s
=> CACHED [linux/arm64->amd64 build 6/6] RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/app . 0.0s
=> CACHED [linux/amd64 stage-1 2/2] COPY --from=build /out/app /app
ECR もこれをサポートしていて Other として上がる。