Skip to content

Commit 89ff2da

Browse files
committed
Publish release Docker images per binary
1 parent ee245ca commit 89ff2da

4 files changed

Lines changed: 108 additions & 17 deletions

File tree

.github/workflows/release.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77

88
permissions:
99
contents: write
10+
packages: write
1011

1112
jobs:
1213
release:
@@ -101,3 +102,60 @@ jobs:
101102
else
102103
gh release create "${TAG_NAME}" dist/* --title "${TAG_NAME}" --notes "Release ${TAG_NAME}"
103104
fi
105+
106+
docker-images:
107+
name: Build and publish ${{ matrix.app }} image
108+
runs-on: ubuntu-latest
109+
needs: release
110+
strategy:
111+
fail-fast: false
112+
matrix:
113+
app:
114+
- edge-gateway
115+
- private-connector
116+
- signurl
117+
118+
steps:
119+
- name: Check out repository
120+
uses: actions/checkout@v4
121+
122+
- name: Set up QEMU
123+
uses: docker/setup-qemu-action@v3
124+
125+
- name: Set up Docker Buildx
126+
uses: docker/setup-buildx-action@v3
127+
128+
- name: Log in to GitHub Container Registry
129+
uses: docker/login-action@v3
130+
with:
131+
registry: ghcr.io
132+
username: ${{ github.actor }}
133+
password: ${{ secrets.GITHUB_TOKEN }}
134+
135+
- name: Prepare image name
136+
id: image
137+
env:
138+
REPOSITORY: ${{ github.repository }}
139+
APP: ${{ matrix.app }}
140+
run: |
141+
set -euo pipefail
142+
repository="${REPOSITORY,,}"
143+
echo "name=ghcr.io/${repository}/${APP}" >> "${GITHUB_OUTPUT}"
144+
145+
- name: Build and push image
146+
uses: docker/build-push-action@v6
147+
with:
148+
context: .
149+
file: ./Dockerfile
150+
platforms: linux/amd64,linux/arm64
151+
push: true
152+
build-args: |
153+
APP=${{ matrix.app }}
154+
tags: |
155+
${{ steps.image.outputs.name }}:${{ github.ref_name }}
156+
labels: |
157+
org.opencontainers.image.title=air3 ${{ matrix.app }}
158+
org.opencontainers.image.description=air3 ${{ matrix.app }} release image
159+
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
160+
org.opencontainers.image.revision=${{ github.sha }}
161+
org.opencontainers.image.version=${{ github.ref_name }}

Dockerfile

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
# syntax=docker/dockerfile:1
22

3-
# Repository foundation image. The binaries are placeholders until runtime behavior
4-
# is implemented, but this build path is intended to remain the multi-binary path.
5-
FROM golang:1.22-alpine AS build
3+
ARG GO_VERSION=1.22
4+
ARG ALPINE_VERSION=3.20
5+
6+
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS build
67
WORKDIR /src
78

8-
COPY go.mod ./
9+
ARG APP=edge-gateway
10+
ARG TARGETOS=linux
11+
ARG TARGETARCH
12+
13+
COPY go.mod go.sum ./
914
RUN go mod download
1015

1116
COPY . .
12-
RUN CGO_ENABLED=0 GOOS=linux go build -o /out/edge-gateway ./cmd/edge-gateway \
13-
&& CGO_ENABLED=0 GOOS=linux go build -o /out/private-connector ./cmd/private-connector \
14-
&& CGO_ENABLED=0 GOOS=linux go build -o /out/signurl ./cmd/signurl
17+
RUN case "${APP}" in \
18+
edge-gateway|private-connector|signurl) ;; \
19+
*) echo "unsupported APP=${APP}" >&2; exit 1 ;; \
20+
esac \
21+
&& targetos="${TARGETOS:-linux}" \
22+
&& targetarch="${TARGETARCH:-$(go env GOARCH)}" \
23+
&& CGO_ENABLED=0 GOOS="${targetos}" GOARCH="${targetarch}" \
24+
go build -trimpath -ldflags="-s -w" -o /out/air3 "./cmd/${APP}"
1525

16-
FROM alpine:3.20
26+
FROM alpine:${ALPINE_VERSION}
1727
RUN adduser -D -H -u 10001 appuser
18-
COPY --from=build /out/ /usr/local/bin/
28+
COPY --from=build /out/air3 /usr/local/bin/air3
1929
USER appuser
2030

21-
# Run the edge gateway by default. Override the command to run another binary,
22-
# for example: docker run --rm air3 /usr/local/bin/private-connector
23-
CMD ["/usr/local/bin/edge-gateway"]
31+
# The selected APP binary is copied to this stable runtime path.
32+
CMD ["/usr/local/bin/air3"]

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ go test ./... -race # run race-enabled Go tests (expected to pass)
6565

6666
Pushing a bare semver-like tag such as `0.0.1` runs the release workflow. The workflow tests the Go packages, validates the Compose file when Docker Compose is available, cross-compiles `edge-gateway`, `private-connector`, and `signurl` for Linux, macOS, and Windows on amd64 and arm64, uploads the packaged artifacts, and publishes them to the GitHub Release for the tag with SHA-256 checksums.
6767

68+
The same release workflow also publishes separate multi-architecture Linux images to GitHub Container Registry. Images are tagged with the release tag:
69+
70+
- `ghcr.io/terion-name/air3/edge-gateway:<tag>`
71+
- `ghcr.io/terion-name/air3/private-connector:<tag>`
72+
- `ghcr.io/terion-name/air3/signurl:<tag>`
73+
74+
Pull a released image with, for example:
75+
76+
```sh
77+
docker pull ghcr.io/terion-name/air3/edge-gateway:0.0.1
78+
docker pull ghcr.io/terion-name/air3/private-connector:0.0.1
79+
docker pull ghcr.io/terion-name/air3/signurl:0.0.1
80+
```
81+
6882
## Docker Compose demo quickstart
6983

7084
The demo starts four runtime services:
@@ -119,4 +133,12 @@ When URL signing is enabled, a ranged request must include the range claim in th
119133

120134
## Docker image
121135

122-
The root `Dockerfile` builds all three binaries into a small runtime image. The Compose demo overrides the command per service to run either `/usr/local/bin/edge-gateway` or `/usr/local/bin/private-connector`.
136+
The root `Dockerfile` builds one selected binary into a small runtime image. Select the command with the `APP` build argument; supported values are `edge-gateway`, `private-connector`, and `signurl`. The selected binary is copied to `/usr/local/bin/air3`, which is the image default command.
137+
138+
```sh
139+
docker build --build-arg APP=edge-gateway -t air3-edge-gateway:dev .
140+
docker build --build-arg APP=private-connector -t air3-private-connector:dev .
141+
docker build --build-arg APP=signurl -t air3-signurl:dev .
142+
```
143+
144+
The Compose demo sets `APP` per service and builds separate local images for `edge-gateway` and `private-connector`.

deploy/compose.yaml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ services:
1818
edge-gateway:
1919
build:
2020
context: ..
21-
image: air3:demo
22-
command: ["/usr/local/bin/edge-gateway"]
21+
args:
22+
APP: edge-gateway
23+
image: air3-edge-gateway:demo
2324
depends_on:
2425
nats:
2526
condition: service_healthy
@@ -54,8 +55,9 @@ services:
5455
private-connector:
5556
build:
5657
context: ..
57-
image: air3:demo
58-
command: ["/usr/local/bin/private-connector"]
58+
args:
59+
APP: private-connector
60+
image: air3-private-connector:demo
5961
depends_on:
6062
nats:
6163
condition: service_healthy

0 commit comments

Comments
 (0)