Operations 20 min read

Building Multi‑Platform Docker Images with Docker Buildx

This tutorial explains how to install Docker Buildx, create and manage builders, and use QEMU emulation or Go cross‑compilation to produce multi‑platform Docker images, covering command syntax, driver options, global BuildKit variables, and how to push or load the resulting images.

Go Programming World
Go Programming World
Go Programming World
Building Multi‑Platform Docker Images with Docker Buildx

Introduction

Docker supports multi‑platform images that can run on different CPU architectures. While the older docker manifest command can create such images, the preferred method today is the docker buildx plugin, which automates the process and improves efficiency.

Installation

buildx is a CLI plugin that extends Docker with BuildKit capabilities. It requires Docker Engine 19.03 or newer. Docker Desktop includes buildx by default; you can verify the version with docker buildx version . For manual installation, download the binary from the GitHub releases page, rename it to docker-buildx , place it in the CLI‑plugins directory ( $HOME/.docker/cli-plugins on Linux/macOS or %USERPROFILE%\.docker\cli-plugins on Windows), and make it executable:

$ chmod +x ~/.docker/cli-plugins/docker-buildx

More details are available in the official documentation.

Building Multi‑Platform Images

Docker calls them Multi‑platform images . When you pull or run such an image, Docker automatically selects the appropriate architecture without exposing the underlying manifest list.

Build Strategies

Use QEMU emulation via BuildKit’s binfmt_misc support (default on Docker Desktop).

Run the same builder on multiple physical nodes (requires hardware for each target platform).

Use multi‑stage Dockerfiles with cross‑compilation (e.g., Go’s GOOS and GOARCH ).

Creating a Builder

List existing builders:

$ docker buildx ls
NAME/NODE       DRIVER/ENDPOINT  STATUS   BUILDKIT PLATFORMS
default *      docker
  default       default          running 20.10.21 linux/arm64, linux/amd64, ...
desktop-linux  docker
  desktop-linux desktop-linux    running 20.10.21 linux/arm64, linux/amd64, ...

Create a new builder named mybuilder :

$ docker buildx create --name mybuilder
mybuilder

Inspect and bootstrap the builder:

$ docker buildx inspect --bootstrap mybuilder
[+] Building 16.8s (1/1) FINISHED
... (output omitted) ...
Name:   mybuilder
Driver: docker-container
Nodes:
  Name:      mybuilder0
  Endpoint:  unix:///var/run/docker.sock
  Status:    running
  Buildkit:  v0.9.3
  Platforms: linux/arm64, linux/amd64, ...

Activate the builder with docker buildx use mybuilder .

Using the Builder

Example Go program ( hello.go ) and module ( go.mod ) are placed in a directory with a multi‑stage Dockerfile :

package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Printf("Hello, %s/%s!\n", runtime.GOOS, runtime.GOARCH)
}
module hello

go 1.20
FROM golang:1.20-alpine AS builder
WORKDIR /app
ADD . .
RUN go build -o hello .

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/hello .
CMD ["./hello"]

Build for both arm64 and amd64 in one command:

$ docker buildx build --platform linux/arm64,linux/amd64 -t jianghushinian/hello-go .

If you omit --push or --load , the result stays in the build cache, producing a warning. Use --push to upload to a registry (after docker login ) or --load to load a single‑platform image locally.

Cross‑Compilation

Modify the Dockerfile to use BuildKit’s automatic platform arguments:

FROM --platform=$BUILDPLATFORM golang:1.20-alpine AS builder
ARG TARGETOS
ARG TARGETARCH
WORKDIR /app
ADD . .
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o hello .

FROM --platform=$TARGETPLATFORM alpine:latest
WORKDIR /app
COPY --from=builder /app/hello .
CMD ["./hello"]

Build with the same command; BuildKit substitutes $BUILDPLATFORM , $TARGETOS , $TARGETARCH , and $TARGETPLATFORM automatically.

Platform‑Related Global Variables

BuildKit defines eight global ARG variables:

Variable

Description

TARGETPLATFORM

Target platform (e.g., linux/amd64)

TARGETOS

OS part of the target platform

TARGETARCH

Architecture part of the target platform

TARGETVARIANT

Variant of the target platform (e.g., v7)

BUILDPLATFORM

Platform where the build is executed

BUILDOS

OS of the build platform

BUILDARCH

Architecture of the build platform

BUILDVARIANT

Variant of the build platform

Example usage:

# Use TARGETPLATFORM directly in FROM
FROM --platform=$TARGETPLATFORM alpine

# Declare ARG before using it in RUN
ARG TARGETPLATFORM
RUN echo "Building for $TARGETPLATFORM"

Deleting a Builder

Remove the builder and its BuildKit container:

$ docker buildx rm mybuilder
mybuilder removed

After removal, docker buildx ls shows only the default builders again.

Feature List

Run docker buildx --help to see all commands, such as bake , prune , stop , etc., for managing builds and cache.

Conclusion

The article demonstrated installing buildx , creating and managing builders, three build strategies (QEMU emulation, multi‑node builds, and cross‑compilation), and how to push or load the resulting multi‑platform images. It also covered BuildKit’s global variables and provided references for further learning.

References

buildx repository: https://github.com/docker/buildx

Installation guide: https://docs.docker.com/build/install-buildx/

Command reference: https://docs.docker.com/engine/reference/commandline/buildx/

Driver documentation: https://docs.docker.com/build/drivers/

Multi‑platform images: https://docs.docker.com/build/building/multi-platform/

Multi‑stage builds: https://docs.docker.com/build/building/multi-stage/

BuildKit docs: https://docs.docker.com/build/buildkit/

Automatic platform args: https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope

Dockercontainermulti-platformQEMUcross compilationBuildKitBuildx
Go Programming World
Written by

Go Programming World

Mobile version of tech blog https://jianghushinian.cn/, covering Golang, Docker, Kubernetes and beyond.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.