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?
2
Answers
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:
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"
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:
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.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: