How to create docker containers for multiple platforms / architectures

First you need to choose a base image that is available for the target platforms as well. Create your Dockerfile as usual and then build the container for different platforms.

This example would create an amd64 and a aarch64 (arm64/v8) image:

# ARM
docker build --platform=linux/aarch64 -t <dockerhub-username>/<image-name>:<version>-aarch64 .
docker push -t <dockerhub-username>/<image-name>:<version>-aarch64

# AMD
docker build --platform=linux/amd64 -t <dockerhub-username>/<image-name>:<version>-amd64 .
docker push -t <dockerhub-username>/<image-name>:<version>-amd64

Based on these you can create a manifest and upload it:

docker manifest create <dockerhub-username>/<image-name>:<version> \
  --amend <dockerhub-username>/<image-name>:<version>-aarch64 \
  --amend <dockerhub-username>/<image-name>:<version>-amd64
docker manifest push <dockerhub-username>/<image-name>:<version>

This would already provide an image <dockerhub-username>/<image-name>:<version> available for amd64 and aarch64 platform on docker hub. But for convenience we also want a latest tag for that manifest:

docker manifest create <dockerhub-username>/<image-name>:latest \
  --amend <dockerhub-username>/<image-name>:<version>-aarch64 \
  --amend <dockerhub-username>/<image-name>:<version>-amd64
docker manifest push <dockerhub-username>/<image-name>:latest

This uses the same hashes as the version uploaded before.

I am not sure if this is the correct or best way, but at least it works. On my M1 mac buildx didn’t work so I fell back to manifests that aren’t that complicated anyway.

Here an example image that was created and uploaded like this: https://registry.hub.docker.com/r/mbopm/cyberchef.