Skip to content
Merged
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
46 changes: 37 additions & 9 deletions content/manuals/build/ci/github-actions/multi-platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ each platform across multiple runners and create manifest list using the

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 a manifest list and push it to Docker Hub.
create manifest lists and push them to 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.
Expand All @@ -121,7 +124,8 @@ on:
push:

env:
REGISTRY_IMAGE: user/app
DOCKERHUB_REPO: docker-user/my-app
GHCR_REPO: ghcr.io/gh-user/my-app

jobs:
build:
Expand All @@ -131,8 +135,6 @@ jobs:
matrix:
platform:
- linux/amd64
- linux/arm/v6
- linux/arm/v7
- linux/arm64
steps:
- name: Prepare
Expand All @@ -144,14 +146,23 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
images: |
${{ env.DOCKERHUB_REPO }}
${{ env.GHCR_REPO }}

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

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

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

Expand All @@ -164,7 +175,7 @@ jobs:
with:
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
outputs: type=image,"name=${{ env.DOCKERHUB_REPO }},${{ env.GHCR_REPO }}",push-by-digest=true,name-canonical=true,push=true

- name: Export digest
run: |
Expand Down Expand Up @@ -198,24 +209,41 @@ jobs:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

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

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
images: |
${{ env.DOCKERHUB_REPO }}
${{ env.GHCR_REPO }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}

- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
$(printf '${{ env.DOCKERHUB_REPO }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.GHCR_REPO }}@sha256:%s ' *)

- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
docker buildx imagetools inspect ${{ env.DOCKERHUB_REPO }}:${{ steps.meta.outputs.version }}
docker buildx imagetools inspect ${{ env.GHCR_REPO }}:${{ steps.meta.outputs.version }}
```

### With Bake
Expand Down