As docker image already become norm these days, multiplatform image is inevitable. What is multiplatform image? Multiplatform image can be pulled by many systems in single tag, so intead using :someversion-arm64
tag or :someversion-amd64
we can :someversion
tag only.
Before buildx
intoduced there is also some hacky way, to made this happed, lets call it manifest manipulation
, in this method image created and pushed separately then manipulating the manifest of docker image tag, making it conjunct/referencing with the image build separately.
Build Flows:
Dockerfile
ARG ARCH=
FROM ${ARCH}debian:latest
RUN apt update && apt install -y python3-minimal && apt clean && rm -rf /var/lib/apt/lists/* && mkdir /data
WORKDIR /data
CMD ["python3","-m","http.server"]
Building the images
$ docker build -t registry-url/application-name:tag-amd64 --build-arg ARCH=amd64/ .
$ docker build -t registry-url/application-name:tag-arm32v7 --build-arg ARCH=arm32v7/ .
$ docker build -t registry-url/application-name:tag-arm64v8 --build-arg ARCH=arm64v8/ .
Pushing the images
$ docker push registry-url/application-name:tag-amd64
$ docker push registry-url/application-name:tag-arm32v7
$ docker push registry-url/appplication-name:tag-arm64v8
Here we had 3 images, with 3 different manifest, then we create a new manifest by using the other images manifest.
Create manifest
$ docker manifest create \
registry-url/application-name:tag-latest \
--amend docker push registry-url/application-name:tag-amd64 \
--amend registry-url/application-name:tag-arm32v7 \
--amend registry-url/appplication-name:tag-arm64v8
Lastly we push the tag-latest
manifest,
Push manifest
$ docker manifest push registry-url/application-name:tag-latest
The current way is using buildx
, by using buildx build docker images become simpler but also need to pay attention few things.
In simple terms:
docker run --rm --privileged tonistiigi/binfmt:latest -install all
docker buildx create --name MultiArch
docker buildx use MultiArch
docker buildx build --push --platform linux/amd64,linux/arm64 -t registry-url/application-name:tag-latest .
What exactly happen?
MultiArch
MultiArch
linux/amd64,linux/arm64
and with tag registry-url/application-name:tag-latest
Let we see more details:
First we run the tonistiigi/binfmt:latest
Then create our builder
dedyms@homelab docker-gitlab-local % docker buildx create --name MultiArch
MultiArch
Remember our Dockerfile before? we need to remove the ARCH
FROM debian:latest
RUN apt update && apt install -y python3-minimal && apt clean && rm -rf /var/lib/apt/lists/* && mkdir /data
WORKDIR /data
CMD ["python3","-m","http.server"]
Now lets build the image:
oh my gosh i forgot run docker buildx use MultiArch
Lets run it again: progressing....
finished
Now lets inspect the image, here im using the image that already pushed, you may replace the registry-url/application-name:tag-latest
to yours
dedyms@homelab apptest % docker buildx imagetools inspect martadinata666/python-http-server:latest
Name: docker.io/martadinata666/python-http-server:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:447c287bcea699a7403990d9a75b4553e91d4dcc9ba0241bdb50c94e8d26f1e0
Manifests:
Name: docker.io/martadinata666/python-http-server:latest@sha256:d1ab736ab3b53005fce1161474716b152749bff4aa56d9cc490c7187ce59a9f1
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm64
Name: docker.io/martadinata666/python-http-server:latest@sha256:3dcef16799d429101ee2a04690d3720e88c7e2919a6621e43a7e4b8f9072fb25
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
sources: