Skip to content

Commit 3ca8b4f

Browse files
authored
Merge pull request #216 from NERSC/ci-build-merge
test merging manifests
2 parents 6a4ef51 + 44af912 commit 3ca8b4f

File tree

4 files changed

+157
-58
lines changed

4 files changed

+157
-58
lines changed

.github/workflows/bake.yml

Lines changed: 135 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: Docker Bake Build and Push
2-
2+
# This is mostly taken from
3+
# here: https://docs.docker.com/build/ci/github-actions/multi-platform/#with-bake
34
on:
45
push:
56
branches: [ main ]
@@ -11,7 +12,46 @@ env:
1112
REGISTRY: ghcr.io/nersc/interactem
1213

1314
jobs:
14-
bake-platform:
15+
prepare:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
outputs:
20+
tag: ${{ steps.meta.outputs.tag }}
21+
services: ${{ steps.services.outputs.services }}
22+
all-images: ${{ steps.services.outputs.all-images }}
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
with:
27+
submodules: false
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Extract metadata
33+
id: meta
34+
run: |
35+
TAG=$(git rev-parse --short=6 HEAD)
36+
echo "tag=${TAG}" >> $GITHUB_OUTPUT
37+
echo "Generated tag: ${TAG}"
38+
39+
- name: Define services
40+
id: services
41+
run: |
42+
# Extract services from the prod group in docker-bake.hcl
43+
SERVICES=$(docker buildx bake prod --print | jq -cr '[.group.prod.targets[]]')
44+
echo "Services found: ${SERVICES}"
45+
echo "services=${SERVICES}" >> $GITHUB_OUTPUT
46+
47+
# Create combined list including base image for merge-manifests
48+
ALL_IMAGES=$(echo ${SERVICES} | jq -c '. + ["interactem"]')
49+
echo "All images (including base): ${ALL_IMAGES}"
50+
echo "all-images=${ALL_IMAGES}" >> $GITHUB_OUTPUT
51+
working-directory: ./docker
52+
53+
build-base:
54+
needs: prepare
1555
strategy:
1656
matrix:
1757
include:
@@ -41,41 +81,46 @@ jobs:
4181
username: ${{ github.actor }}
4282
password: ${{ secrets.GHCR_PAT }}
4383

44-
- name: Extract metadata
45-
id: meta
46-
run: |
47-
# Generate tag from git commit hash (short)
48-
TAG=$(git rev-parse --short=6 HEAD)
49-
echo "tag=${TAG}" >> $GITHUB_OUTPUT
50-
echo "Generated tag: ${TAG}"
51-
52-
- name: Build ${{ matrix.platform }} base image
84+
- name: Build and push base image by digest
85+
id: bake
5386
uses: docker/bake-action@v6
5487
with:
5588
source: .
5689
files: ./docker/docker-bake.hcl
5790
targets: base
5891
set: |
5992
*.platform=${{ matrix.docker-platform }}
93+
${{ github.event_name != 'pull_request' && '*.output=type=image,push-by-digest=true,name-canonical=true,push=true' || '' }}
94+
*.tags=${{ env.REGISTRY }}/interactem
6095
env:
61-
TAG: ${{ steps.meta.outputs.tag }}
96+
TAG: ${{ needs.prepare.outputs.tag }}
6297
CACHE_PLATFORM: ${{ matrix.platform }}
6398

64-
- name: Build ${{ matrix.platform }} images
65-
uses: docker/bake-action@v6
99+
- name: Export digest
100+
if: github.event_name != 'pull_request'
101+
run: |
102+
mkdir -p /tmp/digests
103+
digest="${{ fromJSON(steps.bake.outputs.metadata).base['containerimage.digest'] }}"
104+
touch "/tmp/digests/${digest#sha256:}"
105+
106+
- name: Upload digest
107+
if: github.event_name != 'pull_request'
108+
uses: actions/upload-artifact@v4
66109
with:
67-
source: .
68-
files: ./docker/docker-bake.hcl
69-
targets: prod
70-
set: |
71-
*.platform=${{ matrix.docker-platform }}
72-
env:
73-
TAG: ${{ steps.meta.outputs.tag }}
74-
CACHE_PLATFORM: ${{ matrix.platform }}
110+
name: interactem-digest-${{ matrix.platform }}
111+
path: /tmp/digests/*
112+
if-no-files-found: error
113+
retention-days: 1
75114

76-
bake-push:
77-
needs: bake-platform
78-
runs-on: ubuntu-24.04-arm
115+
build-services:
116+
needs: [prepare, build-base]
117+
strategy:
118+
matrix:
119+
platform:
120+
- { name: amd64, runner: ubuntu-24.04, docker: linux/amd64 }
121+
- { name: arm64, runner: ubuntu-24.04-arm, docker: linux/arm64 }
122+
service: ${{ fromJson(needs.prepare.outputs.services) }}
123+
runs-on: ${{ matrix.platform.runner }}
79124
permissions:
80125
contents: read
81126
packages: write
@@ -95,22 +140,74 @@ jobs:
95140
username: ${{ github.actor }}
96141
password: ${{ secrets.GHCR_PAT }}
97142

98-
- name: Extract metadata
99-
id: meta
100-
run: |
101-
# Generate tag from git commit hash (short)
102-
TAG=$(git rev-parse --short=6 HEAD)
103-
echo "tag=${TAG}" >> $GITHUB_OUTPUT
104-
echo "Generated tag: ${TAG}"
105-
106-
- name: Build and push multiplatform images
143+
- name: Build and push ${{ matrix.service }} by digest
144+
id: bake
107145
uses: docker/bake-action@v6
108146
with:
109147
source: .
110148
files: ./docker/docker-bake.hcl
111-
push: ${{ github.event_name != 'pull_request' }}
112-
targets: prod
149+
targets: ${{ matrix.service }}
113150
set: |
114-
*.cache-to=
151+
*.platform=${{ matrix.platform.docker }}
152+
${{ github.event_name != 'pull_request' && '*.output=type=image,push-by-digest=true,name-canonical=true,push=true' || '' }}
153+
*.tags=${{ env.REGISTRY }}/${{ matrix.service }}
115154
env:
116-
TAG: ${{ steps.meta.outputs.tag }}
155+
TAG: ${{ needs.prepare.outputs.tag }}
156+
CACHE_PLATFORM: ${{ matrix.platform.name }}
157+
158+
- name: Export digest
159+
if: github.event_name != 'pull_request'
160+
run: |
161+
mkdir -p /tmp/digests
162+
digest="${{ fromJSON(steps.bake.outputs.metadata)[matrix.service]['containerimage.digest'] }}"
163+
touch "/tmp/digests/${digest#sha256:}"
164+
165+
- name: Upload digest
166+
if: github.event_name != 'pull_request'
167+
uses: actions/upload-artifact@v4
168+
with:
169+
name: ${{ matrix.service }}-digest-${{ matrix.platform.name }}
170+
path: /tmp/digests/*
171+
if-no-files-found: error
172+
retention-days: 1
173+
174+
merge-manifests:
175+
if: github.event_name != 'pull_request'
176+
needs: [prepare, build-base, build-services]
177+
runs-on: ubuntu-latest
178+
permissions:
179+
contents: read
180+
packages: write
181+
strategy:
182+
matrix:
183+
service: ${{ fromJson(needs.prepare.outputs.all-images) }}
184+
steps:
185+
- name: Set up Docker Buildx
186+
uses: docker/setup-buildx-action@v3
187+
188+
- name: Login to GitHub Container Registry
189+
uses: docker/login-action@v3
190+
with:
191+
registry: ${{ env.REGISTRY }}
192+
username: ${{ github.actor }}
193+
password: ${{ secrets.GHCR_PAT }}
194+
195+
- name: Download digests
196+
uses: actions/download-artifact@v4
197+
with:
198+
path: /tmp/digests
199+
pattern: ${{ matrix.service }}-digest-*
200+
merge-multiple: true
201+
202+
- name: Create manifest list and push
203+
working-directory: /tmp/digests
204+
run: |
205+
# Create manifest
206+
docker buildx imagetools create \
207+
-t ${{ env.REGISTRY }}/${{ matrix.service }}:${{ needs.prepare.outputs.tag }} \
208+
-t ${{ env.REGISTRY }}/${{ matrix.service }}:latest \
209+
$(printf '${{ env.REGISTRY }}/${{ matrix.service }}@sha256:%s ' *)
210+
211+
- name: Inspect image
212+
run: |
213+
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ matrix.service }}:${{ needs.prepare.outputs.tag }}

docker-compose.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ x-backend-base:
66
args:
77
INSTALL_DEV: ${INSTALL_DEV-false}
88
dockerfile: ../docker/Dockerfile.fastapi
9+
additional_contexts:
10+
- interactem-base=docker-image://ghcr.io/nersc/interactem/interactem
911
env_file:
1012
- .env
1113
environment:
@@ -141,6 +143,8 @@ services:
141143

142144
build:
143145
context: backend/
146+
additional_contexts:
147+
- interactem-base=docker-image://ghcr.io/nersc/interactem/interactem
144148
dockerfile: ../docker/Dockerfile.orchestrator
145149

146150

@@ -180,6 +184,8 @@ services:
180184
- "${HOME}/.superfacility/key.pem:/key.pem"
181185
build:
182186
context: backend/
187+
additional_contexts:
188+
- interactem-base=docker-image://ghcr.io/nersc/interactem/interactem
183189
dockerfile: ../docker/Dockerfile.launcher
184190

185191
metrics:
@@ -202,6 +208,8 @@ services:
202208

203209
build:
204210
context: backend/
211+
additional_contexts:
212+
- interactem-base=docker-image://ghcr.io/nersc/interactem/interactem
205213
dockerfile: ../docker/Dockerfile.metrics
206214

207215
prometheus:

docker/docker-bake.hcl

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ target "platform" {
5656
platforms = ["linux/amd64", "linux/arm64"]
5757
}
5858

59+
target "contexts" {
60+
contexts = {
61+
interactem-base = "target:base"
62+
}
63+
}
64+
5965
variable "CACHE_PLATFORM" {
6066
default = "amd64"
6167
}
@@ -72,13 +78,10 @@ target "base" {
7278

7379
// Service definitions
7480
target "operator" {
75-
inherits = ["platform"]
81+
inherits = ["platform", "contexts"]
7682
context = "backend/"
7783
dockerfile = "../docker/Dockerfile.operator"
7884
tags = generate_tags("operator")
79-
contexts = {
80-
interactem-base = "target:base"
81-
}
8285
cache-from = generate_cache_from("operator")
8386
cache-to = generate_cache_to("operator")
8487
}
@@ -93,37 +96,28 @@ target "callout" {
9396
}
9497

9598
target "fastapi" {
96-
inherits = ["platform"]
99+
inherits = ["platform", "contexts"]
97100
context = "backend/"
98101
dockerfile = "../docker/Dockerfile.fastapi"
99102
tags = generate_tags("fastapi")
100-
contexts = {
101-
interactem-base = "target:base"
102-
}
103103
cache-from = generate_cache_from("fastapi")
104104
cache-to = generate_cache_to("fastapi")
105105
}
106106

107107
target "launcher" {
108-
inherits = ["platform"]
108+
inherits = ["platform", "contexts"]
109109
context = "backend/"
110110
dockerfile = "../docker/Dockerfile.launcher"
111111
tags = generate_tags("launcher")
112-
contexts = {
113-
interactem-base = "target:base"
114-
}
115112
cache-from = generate_cache_from("launcher")
116113
cache-to = generate_cache_to("launcher")
117114
}
118115

119116
target "orchestrator" {
120-
inherits = ["platform"]
117+
inherits = ["platform", "contexts"]
121118
context = "backend/"
122119
dockerfile = "../docker/Dockerfile.orchestrator"
123120
tags = generate_tags("orchestrator")
124-
contexts = {
125-
interactem-base = "target:base"
126-
}
127121
cache-from = generate_cache_from("orchestrator")
128122
cache-to = generate_cache_to("orchestrator")
129123
}
@@ -138,13 +132,10 @@ target "frontend" {
138132
}
139133

140134
target "metrics" {
141-
inherits = ["platform"]
135+
inherits = ["platform", "contexts"]
142136
context = "backend/"
143137
dockerfile = "../docker/Dockerfile.metrics"
144138
tags = generate_tags("metrics")
145-
contexts = {
146-
interactem-base = "target:base"
147-
}
148139
cache-from = generate_cache_from("metrics")
149140
cache-to = generate_cache_to("metrics")
150141
}

operators/docker-bake.hcl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ target "base" {
5454
target "operator" {
5555
inherits = [ "common" ]
5656
context = "backend/"
57+
contexts = {
58+
interactem-base = "target:base"
59+
}
5760
dockerfile = "../docker/Dockerfile.operator"
5861
tags = ["${REGISTRY}/operator:${TAG}"]
5962
}

0 commit comments

Comments
 (0)