Multi-Architecture Docker Build Guide

View Source

This guide explains how to build and push multi-architecture Docker images for Malachi.

Prerequisites

  1. Docker Desktop installed (or Docker Engine + QEMU)
  2. Docker Hub account with push permissions
  3. Docker Buildx enabled (comes by default with Docker Desktop)

Initial Setup

1. Log in to Docker Hub

docker login

Enter your credentials when prompted.

2. Configure multi-architecture builder

make docker-buildx-setup

Or manually:

docker buildx create --name malachi-builder --use --bootstrap
docker buildx inspect --bootstrap

Local Build (for testing)

Build only for your current architecture

make docker-build

Multi-architecture build (AMD64 + ARM64) without push

make docker-buildx

Note: The --load flag only works for one architecture at a time. To test both, you need to push to a registry.

Build and Push to Docker Hub

Multi-architecture push

make docker-buildx-push

This will:

  1. Build for linux/amd64 and linux/arm64
  2. Create multi-architecture manifest
  3. Push to Docker Hub with tags:
    • hectorcardoso/malachi:VERSION (e.g.: 0.2.0)
    • hectorcardoso/malachi:latest

Custom push

# Specify different platforms
PLATFORMS=linux/amd64,linux/arm64,linux/arm/v7 make docker-buildx-push

# Use different username
DOCKER_USERNAME=myuser make docker-buildx-push

# Manually specify version
VERSION=1.0.0 make docker-buildx-push

Verify images on Docker Hub

# View available platforms
docker buildx imagetools inspect hectorcardoso/malachi:latest

Expected output:

Name:      docker.io/hectorcardoso/malachi:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:...
           
Manifests: 
  Name:      docker.io/hectorcardoso/malachi:latest@sha256:...
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64
             
  Name:      docker.io/hectorcardoso/malachi:latest@sha256:...
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64

Test on different architectures

macOS with Apple Silicon (ARM64)

docker pull hectorcardoso/malachi:latest
docker run --rm hectorcardoso/malachi:latest uname -m
# Output: aarch64

Linux x86_64 (AMD64)

docker pull hectorcardoso/malachi:latest
docker run --rm hectorcardoso/malachi:latest uname -m
# Output: x86_64

Force a specific architecture

# Force ARM64 even on AMD64
docker run --platform linux/arm64 hectorcardoso/malachi:latest

# Force AMD64 even on ARM64 (with QEMU emulation)
docker run --platform linux/amd64 hectorcardoso/malachi:latest

Automation with GitHub Actions

The workflow in .github/workflows/docker-build.yml automates the process:

  • Push to main: Automatic build and push with latest tag
  • Tag v*: Build and push with specific version (e.g.: v0.2.0 → tag 0.2.0)
  • Pull Request: Build only (no push)

Configure secrets on GitHub

  1. Go to SettingsSecrets and variablesActions
  2. Add the DOCKERHUB_TOKEN secret:

Troubleshooting

Error: "no matching manifest"

This means the image doesn't have a build for your architecture. Solution:

  • Push with make docker-buildx-push
  • Or force emulation: docker run --platform linux/amd64 ...

Builder not found

docker buildx ls
docker buildx create --name malachi-builder --use

Layer cache

The workflow uses GitHub Actions cache to speed up builds:

cache-from: type=gha
cache-to: type=gha,mode=max

Local build very slow

QEMU emulation (for ARM64 on AMD64 or vice versa) is slow. Use:

# Build only for your architecture
docker build -t hectorcardoso/malachi:latest .

Useful commands

# View available builders
docker buildx ls

# Remove builder
docker buildx rm malachi-builder

# Inspect remote image
docker buildx imagetools inspect hectorcardoso/malachi:latest

# View disk space used by build cache
docker buildx du

# Clean build cache
docker buildx prune -af

Summary of Make commands

CommandDescription
make docker-buildTraditional build (current architecture)
make docker-buildx-setupConfigure multi-architecture builder
make docker-buildxMulti-architecture build (no push)
make docker-buildx-pushBuild and push multi-architecture
make docker-runRun container locally
make docker-stopStop and remove container

References