1- name : Publish tutorial docker image
1+ # Recipe based on: https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
2+ name : Build and publish platform dependent docker image
23on :
34 push :
45 branches :
1516 IMAGE_NAME : ${{ github.repository }}
1617
1718jobs :
18- build-and-push-image :
19- runs-on : ubuntu-latest
19+ build :
20+ strategy :
21+ matrix :
22+ os : ["ubuntu-24.04", "ubuntu-24.04-arm"]
23+ runs-on : ${{ matrix.os }}
24+
2025 permissions :
2126 contents : read
2227 packages : write
@@ -25,43 +30,88 @@ jobs:
2530 - name : Checkout repository
2631 uses : actions/checkout@v4
2732
28- - name : Set up QEMU
29- uses : docker/setup-qemu-action@v3
30-
31- - name : Set up Docker Buildx
32- uses : docker/setup-buildx-action@v3
33-
3433 - name : Log in to the Container registry
3534 uses : docker/login-action@v3
3635 with :
3736 registry : ${{ env.REGISTRY }}
3837 username : ${{ github.actor }}
3938 password : ${{ secrets.GITHUB_TOKEN }}
4039
40+ - name : Set up Docker Buildx
41+ uses : docker/setup-buildx-action@v3
42+
4143 - name : Extract metadata (tags, labels) for Docker
4244 id : meta
4345 uses : docker/metadata-action@v5
4446 with :
4547 images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
4648
47- - name : Build Docker image
49+ - name : Set architecture tag (amd64)
50+ if : ${{ matrix.os == 'ubuntu-24.04' }}
51+ run : echo "ARCH_TAG=amd64" >> $GITHUB_ENV
52+
53+ - name : Set architecture tag (arm)
54+ if : ${{ contains(matrix.os, 'arm') }}
55+ run : echo "ARCH_TAG=arm64" >> $GITHUB_ENV
56+
57+ - name : Build and push by digest
58+ id : build
4859 uses : docker/build-push-action@v6
4960 with :
50- context : .
51- load : true
52- push : false
5361 file : docker/Dockerfile
54- platforms : linux/amd64
55- tags : ${{ steps.meta.outputs.tags }}
62+ platforms : ${{ env.ARCH_TAG }}
5663 labels : ${{ steps.meta.outputs.labels }}
64+ outputs : type=image,"name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}",push-by-digest=true,name-canonical=true,push=true
5765
58- - name : Build (arm) and push (amd/arm) Docker image
59- uses : docker/build-push-action@v6
66+ - name : Export digest
67+ run : |
68+ mkdir -p ${{ runner.temp }}/digests
69+ digest="${{ steps.build.outputs.digest }}"
70+ touch "${{ runner.temp }}/digests/${digest#sha256:}"
71+
72+ - name : Upload digest
6073 if : github.event_name == 'push'
74+ uses : actions/upload-artifact@v4
6175 with :
62- context : .
63- push : true
64- file : docker/Dockerfile
65- platforms : linux/amd64,linux/arm64
66- tags : ${{ steps.meta.outputs.tags }}
67- labels : ${{ steps.meta.outputs.labels }}
76+ name : digests-${{ env.ARCH_TAG }}
77+ path : ${{ runner.temp }}/digests/*
78+ if-no-files-found : error
79+ retention-days : 1
80+
81+ merge-and-publish :
82+ if : github.event_name == 'push'
83+ runs-on : ubuntu-latest
84+ needs :
85+ - build
86+ steps :
87+ - name : Download digests
88+ uses : actions/download-artifact@v4
89+ with :
90+ path : ${{ runner.temp }}/digests
91+ pattern : digests-*
92+ merge-multiple : true
93+
94+ - name : Log in to the Container registry
95+ uses : docker/login-action@v3
96+ with :
97+ registry : ${{ env.REGISTRY }}
98+ username : ${{ github.actor }}
99+ password : ${{ secrets.GITHUB_TOKEN }}
100+
101+ - name : Extract metadata (tags, labels) for Docker
102+ id : meta
103+ uses : docker/metadata-action@v5
104+ with :
105+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
106+
107+
108+ - name : Create manifest list and push
109+ working-directory : ${{ runner.temp }}/digests
110+ run : |
111+ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
112+ $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}@sha256:%s ' *)
113+
114+ - name : Inspect image
115+ run : |
116+ docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}:${{ steps.meta.outputs.version }}
117+
0 commit comments