Overview
Multi-arch images bundle variants for different CPU architectures (amd64, arm64, arm/v7, etc.). Mismatches cause errors like:
- no matching manifest for linux/amd64 in the manifest list entries
- exec format error
This guide shows how to diagnose platform issues and correctly select platforms with --platform across docker run, pull, buildx, and Compose.
Quickstart
- Check your host arch: uname -m (amd64 is x86_64, arm64 is aarch64).
- Inspect image platforms: docker buildx imagetools inspect IMAGE.
- Run with explicit platform if needed: docker run --platform linux/amd64 IMAGE.
- For builds, use buildx: docker buildx build --platform linux/amd64,linux/arm64 ...
- In Compose, set platform: linux/amd64 or linux/arm64 per service.
- If emulation is required, install binfmt/qemu and expect slower performance.
Minimal Working Example
Goal: run the same image as amd64 and arm64 on any host and confirm the selected platform inside the container.
Dockerfile:
# Dockerfile
FROM alpine:3.19
CMD ["sh", "-c", "uname -m && cat /etc/alpine-release"]
Build multi-arch and push to a registry (requires BuildKit/buildx):
# 1) Ensure buildx is active
docker buildx create --use --name multi || docker buildx use multi
# 2) Enable emulation (if building for a non-native arch)
docker run --privileged --rm tonistiigi/binfmt --install all
# 3) Build and push a multi-arch image (replace YOURUSER)
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t YOURUSER/alpine-uname:demo \
--push .
Run explicitly as each platform (works even on the opposite host if emulation is installed):
# Runs arm64 variant
docker run --rm --platform linux/arm64 YOURUSER/alpine-uname:demo
# Runs amd64 variant
docker run --rm --platform linux/amd64 YOURUSER/alpine-uname:demo
You should see uname -m output differ (e.g., aarch64 vs x86_64).
Diagnose a multi-arch mismatch
- Identify your host architecture:
uname -m
- Inspect available platforms for an image:
# Buildx inspector (concise and multi-arch aware)
docker buildx imagetools inspect nginx:alpine
# Or the classic manifest inspector
docker manifest inspect --verbose nginx:alpine | jq '.manifests[].platform'
- Typical symptoms:
- no matching manifest: the image tag does not include your target platform.
- exec format error: you pulled the wrong arch variant and the kernel cannot execute it.
Select a platform for run and pull
- Run for a specific platform:
docker run --rm --platform linux/amd64 nginx:alpine
- Pull a specific platform (useful for offline or CI):
docker pull --platform linux/arm64 nginx:alpine
- Set a temporary default for the session:
export DOCKER_DEFAULT_PLATFORM=linux/amd64
Note: On macOS and Windows, Docker always runs Linux containers; pick linux/amd64 or linux/arm64 accordingly.
Compose: set platform per service
# docker-compose.yml
version: "3.8"
services:
web:
image: nginx:alpine
platform: linux/amd64
ports:
- "8080:80"
Apply with:
docker compose up --pull=always --force-recreate
Build correctly with buildx and Dockerfile args
- Cross-build with buildx:
# Build but load only one arch into the local docker images store
docker buildx build --platform linux/amd64 -t app:test --load .
# Build multi-arch and push
docker buildx build --platform linux/amd64,linux/arm64 -t YOURUSER/app:multi --push .
- Use automatic build args for cross-builds in your Dockerfile:
# Dockerfile (multi-arch aware)
# BuildKit provides these at build time: BUILDPLATFORM, TARGETPLATFORM, TARGETOS, TARGETARCH
ARG TARGETPLATFORM
ARG TARGETARCH
FROM --platform=$TARGETPLATFORM alpine:3.19 AS base
RUN echo "Building for $TARGETPLATFORM ($TARGETARCH)"
CMD ["sh", "-lc", "echo runtime arch: $(uname -m)"]
This ensures the correct base image variant is selected during multi-arch builds.
Common fixes by scenario
- Error: no matching manifest for linux/amd64
- Pick another tag that includes linux/amd64, or select a platform present in the manifest list.
- Verify platforms with docker buildx imagetools inspect IMAGE:TAG.
- Error: exec format error
- Pull/run with the right platform (docker run --platform ...).
- Remove the wrong-arch image and re-pull: docker rmi IMAGE && docker pull --platform TARGET ...
- CI on arm64 runners pulling amd64 images
- Set DOCKER_DEFAULT_PLATFORM=linux/amd64 for steps that need x86.
- Use buildx with --platform linux/amd64 or multi-arch as needed.
- Apple Silicon host running x86-only tools
- Use --platform linux/amd64 or Compose platform: linux/amd64. Expect emulation overhead.
Pitfalls
- Not all tags are multi-arch. Pin tags known to include your target platform.
- --platform on docker build requires BuildKit; prefer buildx for multi-arch.
- Changing --platform pulls different layers; your cache may miss. Use registry cache exports when possible.
- Emulation requires binfmt to be installed; some environments disable it.
- In Compose, platform affects run images; building multi-arch images still requires buildx and --platform.
- Container OS is still Linux; do not use darwin/amd64 or windows/amd64 with Linux images.
Performance notes
- Emulated execution (e.g., running linux/amd64 on arm64 via QEMU) is slower—expect 2–5x overhead for CPU-bound tasks.
- Prefer native architecture for long-running or performance-sensitive workloads.
- For builds, offload to a builder node with native CPUs for target platforms, or use buildx with multiple nodes to parallelize.
- Cache wisely: use --cache-to/--cache-from or registry-backed cache to avoid rebuilding per-arch layers repeatedly.
Tiny FAQ
- How do I see which platforms an image supports?
- docker buildx imagetools inspect IMAGE:TAG
- What values can I use with --platform?
- Common: linux/amd64, linux/arm64, linux/arm/v7, linux/s390x, linux/ppc64le.
- I set --platform but Docker still chose another variant during build.
- Use buildx and ensure FROM uses --platform=$TARGETPLATFORM. Classic docker build may ignore multi-arch nuances without BuildKit.
- Do I need to push to create a multi-arch image?
- Yes, manifest lists are registry objects. Use buildx --push to publish combined manifests.
- Can I make a global default?
- Export DOCKER_DEFAULT_PLATFORM in your shell or CI environment.