CI/CD & DevOps Automation
Build Multi-Architecture Docker Images with Buildx and GitHub Actions
Building Cross-Platform Docker Images
Cross-platform Docker builds enable creating images for multiple architectures (linux/amd64, linux/arm64) from a single Dockerfile. Docker Buildx provides the necessary tooling for multi-platform builds across local environments and CI/CD pipelines.
Prerequisites
- Docker Desktop (includes Buildx) or Docker Engine 19.03+
- QEMU (required for building non-native architectures locally)
- Docker Hub or compatible container registry for pushing multi-arch images
Platform-Aware Dockerfiles
Use automatic platform ARGs to conditionally execute instructions based on target architecture:
FROM alpine:latest
ARG TARGETPLATFORM
ARG TARGETARCH
RUN if [ "$TARGETARCH" = "amd64" ]; then \
apk add --no-cache some-amd64-package; \
elif [ "$TARGETARCH" = "arm64" ]; then \
apk add --no-cache some-arm64-package; \
fi
RUN echo "Building for $TARGETPLATFORM"
TARGETPLATFORM is automatically injected by Buildx during multi-platform builds.
Local Setup (macOS & Windows)
Enable Buildx Builder
Docker Desktop includes Buildx, but you must create a builder instance:
docker buildx create --use --name multiarch-builder
docker buildx inspect --bootstrap
The --bootstrap flag initializes the builder and ensures the node is reachable.
Build Multi-Platform Images
Build for multiple architectures using the --platform flag:
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t your-registry/your-image:latest \
--push \
.
The --push flag is required for multi-arch builds since the local daemon cannot load multi-platform manifests directly.
Local Testing with --load
For single-platform local testing, use --load to load the image into your local Docker daemon:
docker buildx build \
--platform linux/amd64 \
-t your-registry/your-image:test \
--load \
.
The --load flag only works with a single platform. Multi-platform builds must use --push.
GitHub Actions
Complete Workflow
Create .github/workflows/docker-build.yml:
name: Build Multi-Platform Images
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
This example uses GitHub Container Registry (ghcr.io). For Docker Hub, change registry to docker.io and use DOCKER_USERNAME/DOCKER_PASSWORD secrets.
Key Actions Explained
docker/setup-qemu-action@v3: Enables QEMU emulation for non-native architecturesdocker/setup-buildx-action@v3: Configures Buildx builder with multi-platform supportdocker/build-push-action@v5: Executes the build with theplatformsparametercache-from/cache-to: Uses GitHub Actions cache to store and retrieve build layers
Distributed Builds (Advanced)
For large images, distribute builds across multiple runners to reduce total build time. Each runner builds a single platform, then manifests are merged. The single-step multi-platform build shown above is preferred for most use cases.
jobs:
build:
strategy:
matrix:
include:
- platform: linux/amd64
tag: linux-amd64
- platform: linux/arm64
tag: linux-arm64
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build for ${{ matrix.platform }}
uses: docker/build-push-action@v5
with:
context: .
platforms: ${{ matrix.platform }}
push: true
tags: ghcr.io/${{ github.repository }}:latest-${{ matrix.tag }}
cache-from: type=gha
cache-to: type=gha,mode=max
merge:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest
run: |
docker buildx imagetools create \
-t ghcr.io/${{ github.repository }}:latest \
ghcr.io/${{ github.repository }}:latest-linux-amd64 \
ghcr.io/${{ github.repository }}:latest-linux-arm64
The merge job runs on a fresh runner and requires its own Buildx setup and registry login to create and push the manifest.
Verification
Inspect the multi-platform manifest:
docker buildx imagetools inspect your-registry/your-image:latest
This displays the manifest list showing all supported platforms.
Runtime Testing
Test execution on specific architectures using QEMU emulation:
# Test on ARM64
docker run --rm --platform linux/arm64 your-registry/your-image:latest uname -m
# Test on AMD64
docker run --rm --platform linux/amd64 your-registry/your-image:latest uname -m
Verify the output matches the expected architecture (aarch64 for ARM64, x86_64 for AMD64).
Share this Guide:
More Guides
API Gateway Showdown: Kong vs Ambassador vs AWS API Gateway for Microservices
Compare Kong, Ambassador, and AWS API Gateway across architecture, performance, security, and cost to choose the right gateway for your microservices.
12 min readGitHub Actions vs GitLab CI vs Jenkins: The Ultimate CI/CD Platform Comparison for 2026
Compare GitHub Actions, GitLab CI, and Jenkins across architecture, scalability, cost, and security to choose the best CI/CD platform for your team in 2026.
7 min readKafka vs RabbitMQ vs EventBridge: Complete Messaging Backbone Comparison
Compare Apache Kafka, RabbitMQ, and AWS EventBridge across throughput, latency, delivery guarantees, and operational complexity to choose the right event-driven architecture for your use case.
4 min readChaos Engineering: A Practical Guide to Failure Injection and System Resilience
Learn how to implement chaos engineering using the scientific method: define steady state, form hypotheses, inject failures, and verify system resilience. This practical guide covers application and infrastructure-level failure injection patterns with code examples.
4 min readScaling PostgreSQL for High-Traffic: Read Replicas, Sharding, and Connection Pooling Strategies
Master PostgreSQL horizontal scaling with read replicas, sharding with Citus, and connection pooling. Learn practical implementation strategies to handle high-traffic workloads beyond single-server limits.
4 min readContinue Reading
API Gateway Showdown: Kong vs Ambassador vs AWS API Gateway for Microservices
Compare Kong, Ambassador, and AWS API Gateway across architecture, performance, security, and cost to choose the right gateway for your microservices.
12 min readGitHub Actions vs GitLab CI vs Jenkins: The Ultimate CI/CD Platform Comparison for 2026
Compare GitHub Actions, GitLab CI, and Jenkins across architecture, scalability, cost, and security to choose the best CI/CD platform for your team in 2026.
7 min readKafka vs RabbitMQ vs EventBridge: Complete Messaging Backbone Comparison
Compare Apache Kafka, RabbitMQ, and AWS EventBridge across throughput, latency, delivery guarantees, and operational complexity to choose the right event-driven architecture for your use case.
4 min read