I’ve managed to build a multi-arch image, but when I do Docker pull on my M1 Mac, it still pulls in the amd64 version instead of the arm64 one.
I didn’t build with buildx because I have architecture-specific binaries to include in my image. So I have two Docker files, create two images which I push. Then I create a manifest that I annotate so that it includes both images:
But when I do docker pull of this image/manifest on my M1, it still pulls in the amd64 version. I can check this by running docker inspect on the pulled image.
I thought Docker would automatically download the image that fits my architecture? Or is something still wrong with the manifest?
Ok, on further investigation, it seems the contents of the image are correct (it includes the statements to download the correct native binary). But the docker inspect command still says it’s made for amd64. So I’m thinking it’s something with the way the image was created or the way it was pushed to the registry.
How did you push the images? Using different tags for both images and a third tag for the multi-arch image?
I guess you folloed these instructions:
As you suspected, docker pull should pull the image with the matching architecture unless you override with the --platform option. If it didn’t work for you, then you probably did not have that architecture which can be because of using the same tag for both images. Althought I am not sure how you could have create the manifest that way, so there is a good chance that I am wrong.
We basically did what you explain. But our thinking now it that we need to build with buildx and have some emulator installed. We’re still not there yet, but once we find out how to do this, I’ll post the solution here.
Docker Desktop has a built-in emulator. You don’t need buildx for that, but to be honest, when I wanted to create my first multi-arch image, I also started with docker manifest and ended up using buildx because it was easier for me and worked perfectly.
Except, I don’t have a single Dockerfile. Because we have architecture-specific binaries that must be included in the container, we have separate Dockerfiles. So I can’t just use buildx and tell it to build for two different architectures based on a single file.
For those coming here for help, I must say we didn’t really get it working. The built images never ran correctly. So what we did was base our image off a multiplatform base image (Java) that already contained the correct binary. Sorry.
Also, thanks @rimelek , the post you mentioned did help. We managed to use multi-stage builds and/or the TARGETOS/TARGETARCH to differentiate.
You’re one of those rare people on the internet who actually posted their experience as you went along. Ive read so many posts where it ended with: “figured it out, bye” that this was a breath of fresh air. Thank you!