Use Buildah to build multi-platform images

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

Use Buildah to build images for multiple CPU architectures. Multi-platform builds create images that work across different hardware platforms, and Docker automatically selects the appropriate image for each deployment target.

Prerequisites

  • A Dockerfile to build the image from
  • (Optional) GitLab runners running on different CPU architectures

Build multi-platform images

To build multi-platform images with Buildah:

  1. Configure separate build jobs for each target architecture.
  2. Create a manifest job that combines the architecture-specific images.
  3. Configure the manifest job to push the combined manifest to your registry.

Running jobs on their respective architectures avoids performance issues from CPU instruction translation. However, you can run both builds on a single architecture if needed. Building for non-native architecture may result in slower build times.

The following example uses two GitLab-hosted runners on Linux:

  • saas-linux-small-arm64
  • saas-linux-small-amd64
stages:
  - build

variables:
  STORAGE_DRIVER: vfs
  BUILDAH_FORMAT: docker
  FQ_IMAGE_NAME: "$CI_REGISTRY_IMAGE:latest"

default:
  image: quay.io/buildah/stable
  before_script:
    - echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY

build-amd64:
  stage: build
  tags:
    - saas-linux-small-amd64
  script:
    - buildah build --platform=linux/amd64 -t $CI_REGISTRY_IMAGE:amd64 .
    - buildah push $CI_REGISTRY_IMAGE:amd64

build-arm64:
  stage: build
  tags:
    - saas-linux-small-arm64
  script:
    - buildah build --platform=linux/arm64/v8 -t $CI_REGISTRY_IMAGE:arm64 .
    - buildah push $CI_REGISTRY_IMAGE:arm64

create_manifest:
  stage: build
  needs: ["build-arm64", "build-amd64"]
  tags:
    - saas-linux-small-amd64
  script:
    - buildah manifest create $FQ_IMAGE_NAME
    - buildah manifest add $FQ_IMAGE_NAME docker://$CI_REGISTRY_IMAGE:amd64
    - buildah manifest add $FQ_IMAGE_NAME docker://$CI_REGISTRY_IMAGE:arm64
    - buildah manifest push --all $FQ_IMAGE_NAME

This pipeline creates architecture-specific images tagged with amd64 and arm64, then combines them into a single manifest available under the latest tag.

Troubleshooting

Build fails with authentication errors

If you encounter registry authentication failures:

  • Verify that CI_REGISTRY_USER and CI_REGISTRY_PASSWORD variables are available.
  • Check that you have push permissions to the target registry.
  • For external registries, ensure authentication credentials are correctly configured in your project’s CI/CD variables.

Multi-platform builds fail

For multi-platform build issues:

  • Verify that base images in your Dockerfile support the target architectures.
  • Check that architecture-specific dependencies are available for all target platforms.
  • Consider using conditional statements in your Dockerfile for architecture-specific logic.