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
2
3
on :
3
4
push :
4
5
branches :
15
16
IMAGE_NAME : ${{ github.repository }}
16
17
17
18
jobs :
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
+
20
25
permissions :
21
26
contents : read
22
27
packages : write
@@ -25,43 +30,88 @@ jobs:
25
30
- name : Checkout repository
26
31
uses : actions/checkout@v4
27
32
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
-
34
33
- name : Log in to the Container registry
35
34
uses : docker/login-action@v3
36
35
with :
37
36
registry : ${{ env.REGISTRY }}
38
37
username : ${{ github.actor }}
39
38
password : ${{ secrets.GITHUB_TOKEN }}
40
39
40
+ - name : Set up Docker Buildx
41
+ uses : docker/setup-buildx-action@v3
42
+
41
43
- name : Extract metadata (tags, labels) for Docker
42
44
id : meta
43
45
uses : docker/metadata-action@v5
44
46
with :
45
47
images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
46
48
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
48
59
uses : docker/build-push-action@v6
49
60
with :
50
- context : .
51
- load : true
52
- push : false
53
61
file : docker/Dockerfile
54
- platforms : linux/amd64
55
- tags : ${{ steps.meta.outputs.tags }}
62
+ platforms : ${{ env.ARCH_TAG }}
56
63
labels : ${{ steps.meta.outputs.labels }}
64
+ outputs : type=image,"name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}",push-by-digest=true,name-canonical=true,push=true
57
65
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
60
73
if : github.event_name == 'push'
74
+ uses : actions/upload-artifact@v4
61
75
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