Build once, run everywhere! Create images that work on ARM Macs, Intel servers, and Raspberry Pi with a single build command.
Configure multi-arch builder
Docker Desktop handles this by default. For other Docker installations, set up buildx:
# Only needed if not using Docker Desktop
# Create and use a new builder
docker buildx create --name multiarch --use
# Verify available platforms
docker buildx ls
Configure platforms
Specify target architectures in your compose file:
services:
app:
build:
context: .
platforms:
- linux/amd64 # Intel/AMD 64-bit
- linux/arm64 # ARM 64-bit (M1/M2 Macs, AWS Graviton)
- linux/arm/v7 # ARM 32-bit (Raspberry Pi)
image: myapp:latest
Build and push
Build for all platforms and push to registry:
# Build for all platforms
docker compose build
# Build and push to registry
docker compose build --push
# Specific service
docker compose build --push app
Platform-specific Dockerfiles
Handle platform differences in your Dockerfile:
FROM --platform=$BUILDPLATFORM node:20 AS builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "Building on $BUILDPLATFORM for $TARGETPLATFORM"
# Platform-specific commands
RUN if [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
echo "ARM v7 specific setup"; \
fi
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine
COPY --from=builder /app /app
CMD ["node", "app.js"]
Development workflow
Different platforms for dev and production:
services:
app:
build:
context: .
platforms:
- ${DOCKER_DEFAULT_PLATFORM:-linux/amd64}
# Production build
app-prod:
build:
context: .
platforms:
- linux/amd64
- linux/arm64
profiles: ["prod"]
Local development:
# Build for current platform only
docker compose build app
# Production multi-platform build
docker compose --profile prod build --push app-prod
Check image platforms
Verify multi-platform support:
# Inspect manifest
docker buildx imagetools inspect myapp:latest
# Output shows:
# MediaType: application/vnd.docker.distribution.manifest.list.v2+json
# Manifests:
# linux/amd64
# linux/arm64
# linux/arm/v7
CI/CD integration
GitHub Actions example:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
run: |
docker compose build --push
Performance tips
Building for multiple platforms takes longer:
services:
# Development - single platform
dev:
build:
context: .
platforms:
- linux/arm64 # Just for M1 Mac
profiles: ["dev"]
# CI/CD - all platforms
prod:
build:
context: .
cache_from:
- type=registry,ref=myapp:buildcache
cache_to:
- type=registry,ref=myapp:buildcache
platforms:
- linux/amd64
- linux/arm64
Common platform combinations
# Modern cloud (AWS, GCP, Azure)
platforms:
- linux/amd64
- linux/arm64
# IoT and edge
platforms:
- linux/arm64
- linux/arm/v7
- linux/arm/v6
# Maximum compatibility
platforms:
- linux/amd64
- linux/arm64
- linux/arm/v7
- linux/386
Pro tip
Docker automatically selects the correct variant of multi-arch images:
# This automatically uses the right platform variant
FROM node:20-alpine
# You can also use platform variables in your Dockerfile
ARG TARGETPLATFORM
RUN echo "Building for $TARGETPLATFORM"
For platform-specific optimization, build separately:
# Build only for ARM64 with specific optimizations
docker compose build --platform linux/arm64
# Build only for AMD64
docker compose build --platform linux/amd64