Building Multi-Platform Container Images with Docker Buildx

Navin Prasad
4 min readMay 12, 2023

--

If your containers are intended to be used on multiple platforms, then building multi-platform container images can be very useful. Building multi-platform container images allows you to create a single image that can be run on different types of systems, such as Intel, ARM, and AMD. This can save you time and effort because you don’t need to build separate container images for each platform, and it can also make it easier to distribute your container images.

Using Docker Buildx

Docker Buildx is a Docker CLI plugin that extends the docker build command with the ability to build container images for multiple platforms and architectures at the same time. It is an experimental feature of Docker version 18.09. Using Docker Buildx, you can build and push container images to multiple platforms with a single command, allowing you to create cross-platform container images that can be used on different types of systems.

How Docker Buildx Works

Docker Buildx works by creating a build “context” that includes the Dockerfile, source code, and build context, and then building the container images for all the specified platforms at the same time.

Steps to Build Multi-Platform Docker Images and Push them to Docker Hub

Step 1: Install Docker Buildx

To install Docker Buildx, run the following command in the terminal: docker buildx install.

Step 2: Enable Experimental Features

To enable experimental features in Docker, add the following line to your Docker configuration file (usually located at ~/.docker/config.json): “experimental”: “enabled”. Restart Docker to apply the changes.

Step 3: Create a New Docker Buildx Builder

To create a new Docker Buildx builder, run the following command: docker buildx create — name mybuilder.

This will create a new builder with the default settings.

Step 4: Switch to the New Builder

To switch to the new builder, run the following command: docker buildx use mybuilder.

This will activate the new builder for all subsequent Docker commands.

Step 5: Check Your Builder’s Capabilities

Run the following command to check your builder’s capability of building multi-platform container images: docker buildx inspect — bootstrap.

docker buildx inspect --bootstrap

Name: mybuilder

Driver: docker-container

Nodes:

Name: mybuilder0

Endpoint: unix:///var/run/docker.sock

Status: running

Buildkit: v0.11.3

Platforms: linux/arm64, linux/amd64, linux/amd64/v2

Note that the image you are pulling from must also support the architectures you plan to target. This can be checked using: docker buildx imagetools inspect alpine:3.16.

docker buildx imagetools inspect alpine:3.16

Name: docker.io/library/alpine:3.16

MediaType: application/vnd.docker.distribution.manifest.list.v2+json

Digest: sha256:1bd67c81e4ad4b8f4a5c1c914d7985336f130e5cefb3e323654fd09d6bcdbbe2

Manifests:

Name: docker.io/library/alpine:3.16@sha256:0b29a7f4d42d6b5d6433ea91322903900e81b95d47d97d909a6e388e840f4f4a

MediaType: application/vnd.docker.distribution.manifest.v2+json

Platform: linux/amd64

Name: docker.io/library/alpine:3.16@sha256:ed4d840b601f052e9d1c3bb843ad11e904d0265936c90c18e8e7bf6dc2f80d41

MediaType: application/vnd.docker.distribution.manifest.v2+json

Platform: linux/arm/v6

Name: docker.io/library/alpine:3.16@sha256:32c3aacc36c2ceb104f43efbd7cf1c0732cf798e088b784b7c02cee27498b0a8

MediaType: application/vnd.docker.distribution.manifest.v2+json

Platform: linux/arm/v7

Name: docker.io/library/alpine:3.16@sha256:3b37be168bb81cf274793cebd596b4a023bdbca6f3b5bc3dfe8974e569b74feb

MediaType: application/vnd.docker.distribution.manifest.v2+json

Platform: linux/arm64/v8

Name: docker.io/library/alpine:3.16@sha256:abc178f562a2827f068bd0e60f48d998179dcd7130cc5036a287e1716536c306

MediaType: application/vnd.docker.distribution.manifest.v2+json

Platform: linux/386

Name: docker.io/library/alpine:3.16@sha256:e6a8ba98c4be90c07b31be6e3315beeaa1fd5269ac215e581babef640a34ed0b

MediaType: application/vnd.docker.distribution.manifest.v2+json

Platform: linux/ppc64le

Name: docker.io/library/alpine:3.16@sha256:1394c85a9984cb03d369381672a1767378b49d8701adfc6337258756052b2eeb

MediaType: application/vnd.docker.distribution.manifest.v2+json

Platform: linux/s390

Step 6: Create a Dockerfile

Create a Dockerfile with the following content:

# syntax=docker/dockerfile:1
FROM alpine:3.16
RUN apk add curl

Step 7: Log in to Docker Hub

Log in to Docker Hub using the following command: docker login.

Enter your Docker Hub username and password when prompted.

Step 8: Build, Tag and Push Your Docker Image

Build and tag your Docker image using the newly created builder and specify the desired platforms. For example, to build and tag an image for Intel x86_64, AMD64, and ARM64 architectures, you can use the following command: docker buildx build — platform linux/amd64,linux/arm64,linux/386 -t your-dockerhub-username/your-image-name:tag.

docker buildx build --platform linux/amd64,linux/arm64 -t navinprasadk/apkaddcurl:v2 . --push

You can specify additional platforms for your image by adding them to the — platform option.

Add the — push command to the above command to instruct the docker CLI to push the Docker image to Docker Hub.

docker buildx build --platform linux/amd64,linux/arm64 -t navinprasadk/apkaddcurl:v2 . --push
[+] Building 22.5s (12/12) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 99B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> resolve image config for docker.io/docker/dockerfile:1 0.8s
=> CACHED docker-image://docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4d6a7782a409b14 0.0s
=> => resolve docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4d6a7782a409b14 0.0s
=> [linux/amd64 internal] load metadata for docker.io/library/alpine:3.16 0.3s
=> [linux/arm64 internal] load metadata for docker.io/library/alpine:3.16 0.6s
=> [linux/arm64 1/2] FROM docker.io/library/alpine:3.16@sha256:1bd67c81e4ad4b8f4a5c1c914d7985336f130e5cefb3e323654fd09d6bcdbbe2 0.0s
=> => resolve docker.io/library/alpine:3.16@sha256:1bd67c81e4ad4b8f4a5c1c914d7985336f130e5cefb3e323654fd09d6bcdbbe2 0.0s
=> [linux/amd64 1/2] FROM docker.io/library/alpine:3.16@sha256:1bd67c81e4ad4b8f4a5c1c914d7985336f130e5cefb3e323654fd09d6bcdbbe2 0.0s
=> => resolve docker.io/library/alpine:3.16@sha256:1bd67c81e4ad4b8f4a5c1c914d7985336f130e5cefb3e323654fd09d6bcdbbe2 0.0s
=> CACHED [linux/amd64 2/2] RUN apk add curl 0.0s
=> CACHED [linux/arm64 2/2] RUN apk add curl 0.0s
=> exporting to image 20.9s
=> => exporting layers 0.1s
=> => exporting manifest sha256:403248829517c743afe783d3931166e800d7d716f7d0d210a9381ca1c45318df 0.0s
=> => exporting config sha256:cc19d353d0f23f8a8f92e2a32cc7d0f5aee98d2352b5fdeb34c06b17600b5c69 0.0s
=> => exporting manifest sha256:595145e572854ce6f2107e012c69be2eb4e148d7759a7535f9325d8b49ed1300 0.0s
=> => exporting config sha256:af6a49b540831ee553433675b3d38c100991995c3d82b5074a5a2d6d931208a9 0.0s
=> => exporting manifest list sha256:55b1de08ad830205a77330b52e3d32740839cc4a6a88e033bdcd954192e749b2 0.0s
=> => pushing layers 18.8s
=> => pushing manifest for docker.io/navinprasadk/apkaddcurl:v2@sha256:55b1de08ad830205a77330b52e3d32740839cc4a6a88e033bdcd954192e749b2 1.9s
=> [auth] navinprasadk/apkaddcurl:pull,push token for registry-1.docker.io

Conclusion

Overall, Docker Buildx is a powerful tool for building multi-platform container images. It can be handy if you need your container images to run on multiple platforms or if you want to take advantage of cloud platforms that support running Docker containers on a variety of platforms. By following the steps in this tutorial, you can easily create cross-platform container images that can be used on different types of systems.

--

--