ReviseAlgo Logo

Building Docker Images

Building Images for Different Architectures (ARM vs x86)

Utilizing Docker Buildx and QEMU to target multiple CPUs.

Interview: Highly relevant in modern platform engineering. You must explain how to build a single container tag that runs seamlessly on both Apple M-series developer laptops and Intel/AMD cloud servers.

Last Updated: June 14, 2026 12 min read

Introduction

For decades, x86 (Intel/AMD) was the unchallenged processor architecture for servers. Today, ARM-based servers (like AWS Graviton) offer comparable performance at 20-40% lower cloud compute cost. Meanwhile, developers increasingly code on ARM-based Apple Silicon (M1/M2/M3) laptops.

This shift introduces compilation mismatches. An image built on a Mac (ARM64) will fail on an Intel cloud node (AMD64). Solving this requires creating Multi-Architecture Images.

Why It Matters

Building multi-arch images ensures developers can test code locally on ARM laptops and deploy identical images to AMD64 cloud nodes without modifying docker files or splitting deployment tags.

How It Works (Buildx and QEMU)

Docker supports cross-platform compilation through two key tools:

1. QEMU Emulation: An open-source emulator that intercepts CPU instructions. If you build an AMD64 image on an ARM64 host, QEMU translates AMD64 system calls to ARM64 in real-time. This is slow but requires no code modifications.
2. Docker Buildx: A command CLI plugin extending Docker build capabilities using the **Moby BuildKit** engine. It manages multi-platform target builders and merges outputs into a single image manifest tag.

Practical Example

Let's set up a custom Docker Buildx driver and compile a multi-arch image supporting both ARM64 and AMD64:

What just happened? We booted a Buildx environment. BuildKit compiled two distinct images (one for AMD64, one for ARM64) using QEMU. Then, it pushed both variants to the registry along with a single Manifest List mapping the tag to both builds.

Quick Quiz

Q1: How does a Docker client determine which binary version to download when pulling a multi-arch tag?

A) The developer must specify the platform at pull time.

B) The client queries the image manifest list, checks the host CPU architecture, and automatically pulls the corresponding layer hashes.

C) The host kernel executes AMD64 binaries using hardware filters.

D) Registry APIs convert binaries on the fly.

Answer: B — Manifest lists act as a router index, letting local engines pull correct CPU binaries automatically.

Scenario-Based Challenge

Production Scenario:

You run your multi-arch image compilation on an ARM-based CI runner. The AMD64 build is taking 35 minutes (7x slower than local build) because of QEMU emulation overhead. How can you speed this up?

View Solution

QEMU emulates CPU commands in software, adding high overhead. To optimize this:

1. **Multi-Node Builders:** Bind a remote x86 server to your Buildx instance:
docker buildx create --name cluster-builder --node node-x86 tcp://x86-server:2376
BuildKit will automatically deploy AMD64 steps to the x86 host, and ARM64 steps to the local ARM host, running both compilations at native speed.

2. **Cross-Compilation:** Restructure your Dockerfile to use compiler target options (like GOARCH=amd64 or cargo --target). This compiles the AMD64 binary natively on the ARM CPU without needing emulation layers.

Interview Questions

1. What is an OCI Manifest List?

An OCI manifest list is a JSON file pointing to multiple individual image manifests. Each entry specifies the target OS (e.g., linux), the CPU architecture (e.g., arm64 or amd64), and the cryptographic digest of that specific image manifest.

2. Can you build a multi-arch image without pushing it to a registry?

No, not directly into local Docker images. Standard Docker engine stores do not support manifest lists. To save multi-arch builds locally, you must export them as a tarball using --output type=docker or use container runtime stores (like containerd) that support multiple platforms.

Production Considerations

Verify your multi-arch outputs. Run docker buildx imagetools inspect myregistry/app:latest to verify that the registry manifest correctly displays both amd64 and arm64 platforms. Testing manifests prevents architecture failures on cloud servers during runtime.