2

I am trying to build a multi-arch image using docker. I am using github actions for the CI. The build using buildx+qemu is fairly slow. So I am trying to build individual images on hosts with the target architecture and then stitch the created manifest to create a manifest list and push the image.

I ran following commands to achieve this

  • docker buildx build --progress=plain --platform linux/arm64 -o type=oci,dest=/tmp/abc-arm64.tar -t abc-arm64:1.2.0 -f Dockerfile .
  • docker buildx build --progress=plain --platform linux/amd64 -o type=oci,dest=/tmp/abc-amd64.tar -t abc-amd64:1.2.0 -f Dockerfile .
  • Uploaded these tar files from different jobs and then downloaded into one job
  • docker load --input /tmp/abc-arm64.tar
  • docker load --input /tmp/abc-amd64.tar
  • docker buildx imagetools create --dry-run -t abc:1.2.0 abc-amd64:1.2.0 abc-arm64:1.2.0

but I am getting following error

error: multiple repositories currently not supported, found map[docker.io/library/abc:{} docker.io/library/abc-amd64:{} docker.io/library/abc-arm64:{}]

Is there a way to stitch multi-arch image without pushing individual images to a remote docker registry?

Puneet
  • 69
  • 8

2 Answers2

1

This can be done with regclient/regctl (disclosure, I'm the author). There is a GitHub Action available to install it at: https://github.com/regclient/actions

First, build two images. In this case I'm rebuilding regctl itself, but you can build your own image:

$ docker buildx build --platform linux/arm64 -f build/Dockerfile.regctl.buildkit -o type=oci,dest=test/build-regctl-arm64.tar .
...

$ docker buildx build --platform linux/amd64 -f build/Dockerfile.regctl.buildkit -o type=oci,dest=test/build-regctl-amd64.tar .
...

Import each export into an OCI Layout directory, which regctl needs (this avoids scanning the tar contents multiple times to search for individual blobs in the tar). I've giving each a separate tag here, which lets me keep everything under one directory, but that's not required.

$ regctl image import ocidir://test/build-regctl:amd64 test/build-regctl-amd64.tar 

$ regctl image import ocidir://test/build-regctl:arm64 test/build-regctl-arm64.tar 

Use regctl index create to build an index (manifest list) from the two images in the OCI Layout, this also copies by digest to the registry:

$ regctl index create localhost:5000/test/build-regctl --ref ocidir://test/build-regctl:amd64 --ref ocidir://test/build-regctl:arm64

$ regctl manifest get localhost:5000/test/build-regctl
Name:        localhost:5000/test/build-regctl
MediaType:   application/vnd.oci.image.index.v1+json
Digest:      sha256:ad494163a836d5c527a3b45e9372d7acd2ecfdc265c1807662df90461a84aeea
             
Manifests:   
             
  Name:      localhost:5000/test/build-regctl:latest@sha256:4e0c527c7ea92df8cf496348dbde89e02ce5dcd9df060c4b71d3e07f20ca6bf0
  Digest:    sha256:4e0c527c7ea92df8cf496348dbde89e02ce5dcd9df060c4b71d3e07f20ca6bf0
  MediaType: application/vnd.oci.image.manifest.v1+json
  Platform:  linux/amd64
             
  Name:      localhost:5000/test/build-regctl:latest@sha256:8c58951efc4b012c69514b7fc8995f7d7ace49a242ddae8841b473bf87b36d60
  Digest:    sha256:8c58951efc4b012c69514b7fc8995f7d7ace49a242ddae8841b473bf87b36d60
  MediaType: application/vnd.oci.image.manifest.v1+json
  Platform:  linux/arm64
BMitch
  • 231,797
  • 42
  • 475
  • 450
-1

Not sure if you are intentionally trying to build tar files, but if you want to build multiplatform images at once and push them to your registry you can use a single command:

docker buildx build \
    --platform 'linux/amd64,linux/arm64' \
    -f 'Dockerfile' \
    -t yourregistry/abc:1.2.0 \
    --push \
    .

It will build and push two images for amd64 and arm64 and create an image list with 1.2.0 tag. And when you later want to use an image on a specific platform, pulling "yourregistry/abc:1.2.0" will automatically resolve the image for your platform to download.

P.S. "docker buildx imagetools create" has added support for multiple repositories in v0.9.0: "buildx imagetools create command can now create new multi-platform images even if the source subimages are located on different repositories or registries #1137"

Roman Bats
  • 1,775
  • 3
  • 30
  • 40