Images für ARM und AMD64 bauen - Docker Buildx und Multi-Platform
Images für ARM und AMD64 bauen - Docker Buildx und Multi-Platform
Raspberry Pi, Apple Silicon (M1/M2/M3), AWS Graviton — ARM-basierte Systeme sind keine Ausnahme mehr. Ein Image für mehrere Plattformen zu bauen ist mit docker buildx einfacher als man denkt.
Warum das relevant ist
Ein Image, das auf AMD64 (x86_64) gebaut wurde, läuft auf ARM nicht nativ — der Kernel emuliert die andere Architektur, was deutlich langsamer ist. Native ARM-Images laufen auf ARM-Hardware ohne Overhead.
Mit Multi-Platform-Builds liefert docker pull automatisch das zur Plattform passende Image.
Buildx einrichten
Buildx ist seit Docker 19.03 enthalten, muss aber als aktiver Builder eingerichtet werden:
# Neuen Builder erstellen und aktivieren
docker buildx create --name multibuilder --use
# QEMU für Cross-Compilation installieren (einmalig)
docker run --privileged --rm tonistiigi/binfmt --install all
# Builder prüfen
docker buildx inspect --bootstrap
Der Builder zeigt die unterstützten Plattformen:
Platforms: linux/amd64, linux/arm64, linux/arm/v7, linux/386
Multi-Platform-Image bauen und pushen
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myregistry/myapp:1.2.3 \
--push \
.
--push ist hier notwendig — Multi-Platform-Images können nicht in den lokalen Docker-Cache geladen werden, weil der lokale Cache nur eine Plattform hält. Das Image geht direkt in die Registry.
Manifest prüfen
Ob ein Image wirklich für mehrere Plattformen verfügbar ist:
docker manifest inspect myregistry/myapp:1.2.3
Im Output sind alle Plattform-Varianten mit ihren Digests aufgelistet.
Plattform-spezifische Logik im Dockerfile
In seltenen Fällen braucht man plattformabhängige Befehle. BUILDPLATFORM und TARGETPLATFORM sind eingebaute Build-Argumente:
FROM --platform=$BUILDPLATFORM golang:1.21 AS builder
ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH
WORKDIR /app
COPY . .
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o server .
FROM alpine:3.18
COPY --from=builder /app/server /app/server
CMD ["/app/server"]
Go cross-kompiliert nativ — kein QEMU nötig, der Build läuft auf dem Build-Host in voller Geschwindigkeit.
Wann native Builder sinnvoll sind
QEMU-Emulation funktioniert für die meisten Builds — aber bei aufwändigen nativen Compilierungen (C-Extensions, Rust) ist die Emulation deutlich langsamer. In diesem Fall: nativen ARM-Builder über docker buildx create --append zum Builder-Pool hinzufügen, damit jede Plattform nativ gebaut wird.