Apple Silicon laptops, Graviton servers and Raspberry Pis all need arm64 images alongside amd64.
An image built on an amd64 machine contains amd64 binaries and won't run natively on arm64 (and vice versa). A multi-platform image is one tag that points to an image index listing a separate image per platform; the client automatically pulls the one matching its architecture.
Build one with buildx:
docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/acme/api:1.4.2 --push .The classic image store can't hold multi-platform images locally, so you either --push straight to a registry or use the containerd image store (the default in recent Docker Desktop installs), which can load them. A builder with the docker-container driver (docker buildx create --use) also works.
There are two ways to produce foreign-architecture binaries:
- Emulation with QEMU: BuildKit runs arm64
RUNsteps under emulation. Docker Desktop includes it; on Linux install it withdocker run --privileged --rm tonistiigi/binfmt --install all. It's simple but can be 5 to 20 times slower for compile-heavy steps. - Cross-compilation: run the build stage on the builder's native platform and tell the compiler the target. BuildKit provides
BUILDPLATFORM,TARGETPLATFORM,TARGETOSandTARGETARCHas automatic build args:
FROM --platform=$BUILDPLATFORM golang:1.25 AS build
ARG TARGETOS TARGETARCH
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /app .Go, Rust and Zig cross-compile easily, and Node or Python apps without native modules don't need compiling at all.
A third option is native builder nodes per architecture (docker buildx create --append) or arm64 CI runners. Check the result with docker buildx imagetools inspect <image>.
Example
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:1.25 AS build
ARG TARGETOS TARGETARCH
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /out/api ./cmd/api
FROM gcr.io/distroless/static-debian12
COPY --from=build /out/api /api
ENTRYPOINT ["/api"]
# docker buildx build --platform linux/amd64,linux/arm64 \
# -t ghcr.io/acme/api:1.4.2 --push .
# docker buildx imagetools inspect ghcr.io/acme/api:1.4.2
# Platform: linux/amd64 ... Platform: linux/arm64Remember
- One tag, one image index, one image per platform
- --platform a,b with --push (or the containerd image store to load locally)
- Emulation is easy but slow; cross-compile with FROM --platform=$BUILDPLATFORM
- TARGETOS/TARGETARCH are provided automatically
Watch out for
- Running every compile step under QEMU emulation and accepting 30-minute builds that cross-compilation would cut to minutes.