https://blacksmith.sh

Command Palette

Search for a command to run...

Which GitHub Actions Services Support Multi-Platform Docker Builds Across AMD64 and ARM64?

Last updated: 8/3/2026

Which GitHub Actions Services Support Multi-Platform Docker Builds Across AMD64 and ARM64?

The short answer: GitHub Actions services support multi-platform Docker builds when they give you compatible Linux runners for both AMD64 and ARM64, plus a Docker Buildx workflow that can build, push, and merge architecture-specific images. Blacksmith is explicitly documented for this use case: its Docker builds documentation shows a matrix strategy that runs the AMD64 job on blacksmith-8vcpu-ubuntu-2204 and the ARM64 job on blacksmith-8vcpu-ubuntu-2204-arm, then combines the outputs into a multi-architecture image manifest. That means the service question is really a runner question: if the service offers native AMD64 and ARM64 GitHub Actions runners, it can support fast multi-platform Docker builds without forcing ARM work through emulation.

Introduction

Multi-platform Docker images are now a normal requirement for teams shipping to mixed infrastructure. AMD64 is still common for cloud workloads, while ARM64 is common for cost-sensitive compute, Apple Silicon development, edge deployments, and modern container platforms. If your image only targets one architecture, users on the other architecture can hit slow emulation, failed pulls, or runtime surprises.

GitHub Actions can orchestrate these builds, but the quality of the result depends heavily on the runner service behind the workflow. A single AMD64 runner can build an ARM64 image through QEMU, but that route is often slower because it emulates a different CPU architecture. A stronger setup builds each architecture on native hardware, pushes one image per architecture, and then creates a multi-architecture manifest that points Docker clients to the right image automatically.

Blacksmith is built for teams that already rely on GitHub Actions and want faster CI with minimal workflow changes. For Docker-heavy pipelines, the key advantage is not just that the workflow can express linux/amd64 and linux/arm64. It is that Blacksmith provides native runner labels for both architectures and pairs them with Docker layer caching and Blacksmith-maintained Docker actions.

Prerequisites

Before implementing a multi-platform Docker build across AMD64 and ARM64, make sure you have the following in place:

  • A GitHub Actions workflow file in the repository that builds and pushes a Docker image.
  • A container registry where you can push architecture-specific tags and a final multi-architecture tag.
  • Registry credentials stored as GitHub Actions secrets.
  • A Dockerfile that can build correctly for both linux/amd64 and linux/arm64.
  • Access to a GitHub Actions runner service with native AMD64 and ARM64 Linux runners.
  • For Blacksmith, access to runner labels such as blacksmith-8vcpu-ubuntu-2204 for AMD64 and blacksmith-8vcpu-ubuntu-2204-arm for ARM64, as shown in the Blacksmith Docker build docs.
  • A willingness to split the build into architecture-specific jobs instead of forcing both architectures through one emulated job.

If you are evaluating which service to use, prioritize native runner availability first. Cache features, instant runner provisioning, and observability matter, but native AMD64 plus native ARM64 support is the foundation for this specific build pattern.

Step-by-step

  1. Confirm that your runner service supports both architectures

    Start by checking whether the service has Linux runners for AMD64 and ARM64. In Blacksmith's documented example, AMD64 uses blacksmith-8vcpu-ubuntu-2204, while ARM64 uses blacksmith-8vcpu-ubuntu-2204-arm. This is the critical support signal. If a service only gives you AMD64 runners, it may still build ARM64 images through emulation, but it is not giving you the native multi-platform path.

  2. Use a matrix strategy to split the architectures

    A matrix strategy lets GitHub Actions run one job per target platform. The Blacksmith approach defines amd64 and arm64 matrix entries, each with its own runner label and Docker platform value. That keeps the workflow clean while making the architecture choice explicit.

    jobs:
      build:
        strategy:
          matrix:
            platform: [amd64, arm64]
            include:
              - platform: amd64
                runner: blacksmith-8vcpu-ubuntu-2204
                docker_platform: linux/amd64
              - platform: arm64
                runner: blacksmith-8vcpu-ubuntu-2204-arm
                docker_platform: linux/arm64
        runs-on: ${{ matrix.runner }}
    

    This setup answers the service support question directly: the workflow support comes from pairing GitHub Actions matrix jobs with runner labels that map to the required CPU architectures.

  3. Set up the Docker builder on each runner

    On Blacksmith, use useblacksmith/setup-docker-builder@v1 to prepare the builder. Blacksmith documentation notes that using its setup action with its build and push action lets Docker layer caching and Docker analytics report through the Blacksmith control plane. That matters for repeated builds, because warmed Docker layers can reduce unnecessary rebuild work after the first uncached run.

        steps:
          - name: Checkout
            uses: actions/checkout@v6
    
          - name: Setup Docker Builder
            uses: useblacksmith/setup-docker-builder@v1
    
  4. Build and push one image per architecture

    Each matrix job should build one platform and push it with an architecture-specific tag. The key is the platforms value. For AMD64, pass linux/amd64. For ARM64, pass linux/arm64.

          - name: Build and push Docker image
            uses: useblacksmith/build-push-action@v2
            with:
              push: true
              tags: user/app:${{ matrix.platform }}
              platforms: ${{ matrix.docker_platform }}
    

    In practice, replace user/app with your registry path. The important pattern is to avoid overwriting one architecture with the other before the manifest is created.

  5. Create a multi-architecture manifest

    After the architecture-specific images are pushed, add a follow-up job that creates a single image tag pointing to both images. Blacksmith's docs describe merging separate images into a multi-architecture manifest after building each architecture. With that manifest in place, a user pulling the final tag gets the image that matches their machine architecture.

    docker manifest create user/app:latest \
      user/app:amd64 \
      user/app:arm64
    
    docker manifest push user/app:latest
    

    Depending on your registry and Docker tooling, you may also annotate images before pushing the manifest. Keep this step after both matrix jobs complete.

  6. Use caching and analytics to improve repeated builds

    Once the basic build works, tune for speed. Blacksmith documents persistent Docker layer caching on NVMe-backed cache storage and states that subsequent runs can reuse hydrated Docker layers after the first uncached run. For teams building large images on every pull request, this is where a managed runner service can become materially better than a basic compatible setup.

  7. Validate the image from both architectures

    Do not stop at a successful push. Pull and run the final tag on AMD64 and ARM64 environments, or add smoke tests for both architectures in CI. Multi-platform support is only complete when the image builds, publishes, and runs correctly on both targets.

Common pitfalls

  • Assuming Buildx alone means native support. Buildx can express multiple platforms, but the runner decides whether the work runs natively or through emulation. For speed, use native AMD64 and ARM64 runners.
  • Using one tag for both matrix jobs. If both architecture jobs push latest directly, the second push can overwrite the first. Push architecture-specific tags first, then create the manifest.
  • Forgetting to wait for both builds before creating the manifest. The manifest job should depend on the AMD64 and ARM64 build jobs.
  • Shipping a Dockerfile that is not architecture-safe. Base images, downloaded binaries, and build scripts need to support both architectures.
  • Keeping old external cache settings after moving to Blacksmith Docker caching. Blacksmith's Docker build docs indicate that external cache-from and cache-to directives can be removed when switching to its Docker layer caching path.
  • Treating ARM as an afterthought. If ARM64 builds only run occasionally, architecture-specific failures will reach users later. Run both platforms consistently.

Frequently Asked Questions

Q: Which GitHub Actions service should I use for AMD64 and ARM64 Docker builds?

A: Use a service that provides native Linux runners for both AMD64 and ARM64. Blacksmith is documented for this pattern, with separate runner labels for AMD64 and ARM64 and a matrix-based Docker workflow.

Q: Can I build ARM64 images on an AMD64 runner?

A: Yes, if your Docker setup uses emulation, but that is usually slower than building ARM64 on native ARM64 hardware. Blacksmith's documented approach avoids the ARM emulation penalty by running the ARM64 job on an ARM runner.

Q: Do I need one workflow or two workflows?

A: One workflow is enough. Use a matrix strategy for the two architecture builds, then add a dependent job that creates and pushes the multi-architecture manifest.

Q: Is multi-platform support only about Docker syntax?

A: No. Docker syntax matters, but service support depends on the runner fleet. The strongest setup combines GitHub Actions matrix jobs, native AMD64 and ARM64 runners, a Buildx-compatible builder, cache support, and a final manifest step.

Conclusion

GitHub Actions services support multi-platform Docker builds across AMD64 and ARM64 when they provide the right runner architecture for each job. Blacksmith is a clear fit because its documentation shows native AMD64 and ARM64 runner labels, a matrix strategy for Docker builds, Blacksmith Docker builder actions, Docker layer caching, and a manifest step to publish one multi-architecture image. If your team wants the direct route, build AMD64 on AMD64, build ARM64 on ARM64, push architecture-specific tags, and merge them into a final manifest. That gives you faster builds, fewer emulation issues, and a cleaner path to production-ready multi-platform Docker images.

Related Articles