Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: use arm-native gha runners for distributed multi-platform #21854

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 18 additions & 23 deletions content/manuals/build/ci/github-actions/multi-platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,23 +100,22 @@ jobs:

## Distribute build across multiple runners

In the previous example, each platform is built on the same runner which can
take a long time depending on the number of platforms and your Dockerfile.

To solve this issue you can use a matrix strategy to distribute the build for
each platform across multiple runners and create manifest list using the
Building multiple platforms on the same runner can significantly extend build
times, particularly when dealing with complex Dockerfiles or a high number of
target platforms. By distributing platform-specific builds across multiple
runners using a matrix strategy, you can drastically reduce build durations and
streamline your CI pipeline. These examples demonstrate how to allocate each
platform build to a dedicated runner, including ARM-native runners where
applicable, and create a unified manifest list using the
[`buildx imagetools create` command](/reference/cli/docker/buildx/imagetools/create.md).

The following workflow will build the image for each platform on a dedicated
runner using a matrix strategy and push by digest. Then, the `merge` job will
create manifest lists and push them to two registries:
The workflow also highlights tagging and labeling using the [Docker Metadata action](https://github.com/docker/metadata-action),
pushing platform-specific images by digest, and creating manifest lists for two
registries:

- Docker Hub: `docker.io/docker-user/my-app`
- GitHub Container Registry: `ghcr.io/gh-user/my-app`

This example also uses the [`metadata` action](https://github.com/docker/metadata-action)
to set tags and labels.

```yaml
name: ci

Expand All @@ -129,13 +128,15 @@ env:

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
include:
- platform: linux/amd64
os: ubuntu-latest
- platform: linux/arm64
os: ubuntu-24.04-arm
runs-on: ${{ matrix.os }}
steps:
- name: Prepare
run: |
Expand Down Expand Up @@ -163,9 +164,6 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

Expand Down Expand Up @@ -337,13 +335,13 @@ jobs:
retention-days: 1

build:
runs-on: ubuntu-latest
needs:
- prepare
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
runs-on: ${{ startsWith(matrix.platform, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
steps:
- name: Prepare
run: |
Expand All @@ -355,16 +353,13 @@ jobs:
with:
name: bake-meta
path: ${{ runner.temp }}

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

Expand Down