Skip to content

Commit 383569c

Browse files
committed
docker publishing pipeline for riverproui
1 parent 6e5043d commit 383569c

3 files changed

Lines changed: 171 additions & 43 deletions

File tree

.github/workflows/docker.yaml

Lines changed: 133 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,27 @@ on:
99
pull_request:
1010
branches:
1111
- "master"
12+
workflow_dispatch:
13+
inputs:
14+
ref:
15+
description: "Tag to build (e.g. v0.1.0)"
16+
required: true
1217

1318
env:
1419
IMAGE_NAME: ${{ github.repository }}
1520
REGISTRY: ghcr.io
1621

1722
jobs:
18-
build:
19-
name: Build Docker image
20-
runs-on: ubuntu-latest
23+
build-riverui:
24+
name: "Build Docker image: riverui"
25+
runs-on: ${{ matrix.runner }}
2126
strategy:
2227
matrix:
23-
docker_platform:
24-
- linux/amd64
25-
- linux/arm64
26-
- linux/arm64/v8
28+
include:
29+
- docker_platform: linux/amd64
30+
runner: ubuntu-latest
31+
- docker_platform: linux/arm64
32+
runner: ubuntu-24.04-arm64
2733
outputs:
2834
tags: ${{ steps.meta.outputs.tags }}
2935
labels: ${{ steps.meta.outputs.labels }}
@@ -36,15 +42,14 @@ jobs:
3642
steps:
3743
- name: Checkout
3844
uses: actions/checkout@v4
45+
with:
46+
ref: ${{ inputs.ref || github.ref }}
3947

4048
- name: Prepare
4149
run: |
4250
platform=${{ matrix.docker_platform }}
4351
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
4452
45-
- name: Set up QEMU
46-
uses: docker/setup-qemu-action@v3
47-
4853
- name: Set up Docker Buildx
4954
uses: docker/setup-buildx-action@v3
5055

@@ -59,7 +64,7 @@ jobs:
5964
id: meta
6065
uses: docker/metadata-action@v5
6166
with:
62-
images: ghcr.io/${{ github.repository }}
67+
images: ghcr.io/${{ env.IMAGE_NAME }}
6368
labels: |
6469
org.opencontainers.image.source=https://github.com/riverqueue/riverui
6570
org.opencontainers.image.description="River UI is a web-based user interface for River, a fast and reliable background job system."
@@ -69,6 +74,7 @@ jobs:
6974
type=ref,event=pr
7075
type=semver,pattern={{version}}
7176
type=semver,pattern={{major}}.{{minor}}
77+
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
7278
7379
- name: Build and push to GitHub Container Registry
7480
id: build
@@ -98,63 +104,150 @@ jobs:
98104
- name: Upload digest
99105
uses: actions/upload-artifact@v4
100106
with:
101-
name: digests-${{ env.PLATFORM_PAIR }}
107+
name: digests-oss-${{ env.PLATFORM_PAIR }}
102108
path: /tmp/digests/*
103109
if-no-files-found: error
104110
retention-days: 1
105111

106-
merge:
107-
name: Merge and publish image manifests
112+
build-riverproui:
113+
name: "Build Docker image: riverproui"
108114
runs-on: ubuntu-latest
109-
needs:
110-
- build
115+
# TODO: disabled for testing
116+
# if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
111117
permissions:
118+
attestations: write
112119
contents: read
113120
id-token: write
114-
packages: write
115121

116122
steps:
117123
- name: Checkout
118124
uses: actions/checkout@v4
119-
120-
- name: Download digests
121-
uses: actions/download-artifact@v4
122125
with:
123-
path: /tmp/digests
124-
pattern: digests-*
125-
merge-multiple: true
126+
ref: ${{ inputs.ref || github.ref }}
127+
128+
- name: Set TAG
129+
run: echo "TAG=${{ inputs.ref || github.ref_name }}" >> $GITHUB_ENV
130+
131+
- name: Validate TAG
132+
run: |
133+
if [[ ! "$TAG" == v* ]]; then
134+
echo "Tag must start with 'v'"
135+
exit 1
136+
fi
137+
138+
- name: Set up QEMU
139+
uses: docker/setup-qemu-action@v3
126140

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

130-
- name: Login to GitHub Container Registry
131-
uses: docker/login-action@v3
144+
- name: Docker meta for Pro
145+
id: meta-pro
146+
uses: docker/metadata-action@v5
132147
with:
133-
registry: ${{ env.REGISTRY }}
134-
username: ${{ github.actor }}
135-
password: ${{ secrets.GITHUB_TOKEN }}
148+
images: riverqueue.com/riverproui
149+
labels: |
150+
org.opencontainers.image.source=https://github.com/riverqueue/riverui
151+
org.opencontainers.image.description="River UI Pro is a web-based user interface for River, with pro features."
152+
org.opencontainers.image.licenses=MPL-2.0
153+
tags: |
154+
type=semver,pattern={{version}}
155+
type=semver,pattern={{major}}.{{minor}}
156+
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
136157
137-
- name: Docker meta
138-
id: meta
158+
- name: Build and export to OCI
159+
uses: docker/build-push-action@v6
160+
with:
161+
context: .
162+
file: Dockerfile.pro
163+
platforms: linux/amd64,linux/arm64
164+
provenance: true
165+
push: false
166+
tags: ${{ steps.meta-pro.outputs.tags }}
167+
labels: ${{ steps.meta-pro.outputs.labels }}
168+
outputs: type=oci,dest=/tmp/oci
169+
170+
- name: Upload OCI artifact
171+
uses: actions/upload-artifact@v4
172+
with:
173+
name: pro-oci
174+
path: /tmp/oci
175+
retention-days: 1
176+
177+
publish-riverproui:
178+
name: "Publish Docker image: riverproui"
179+
runs-on: ubuntu-latest
180+
needs:
181+
- build-riverproui
182+
# TODO: disabled for testing
183+
# if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
184+
185+
steps:
186+
- name: Checkout
187+
uses: actions/checkout@v4
188+
with:
189+
ref: ${{ inputs.ref || github.ref }}
190+
191+
- name: Download OCI artifact
192+
uses: actions/download-artifact@v4
193+
with:
194+
name: pro-oci
195+
path: /tmp/oci
196+
197+
- name: Install jq
198+
run: sudo apt-get update && sudo apt-get install -y jq
199+
200+
- name: Install AWS CLI
201+
uses: unfor19/install-aws-cli-action@v1
202+
with:
203+
version: 2
204+
verbose: false
205+
arch: amd64
206+
207+
- name: Configure AWS CLI
208+
run: |
209+
aws configure set aws_access_key_id ${{ secrets.R2_ACCESS_KEY_ID }}
210+
aws configure set aws_secret_access_key ${{ secrets.R2_SECRET_ACCESS_KEY }}
211+
aws configure set default.region auto
212+
213+
- name: Docker meta for Pro
214+
id: meta-pro
139215
uses: docker/metadata-action@v5
140216
with:
141-
images: ghcr.io/${{ env.IMAGE_NAME }}
217+
images: riverqueue.com/riverproui
142218
labels: |
143219
org.opencontainers.image.source=https://github.com/riverqueue/riverui
144-
org.opencontainers.image.description="River UI is a web-based user interface for River, a fast and reliable background job system."
220+
org.opencontainers.image.description="River UI Pro is a web-based user interface for River, a fast and reliable background job system, with pro features enabled."
145221
org.opencontainers.image.licenses=MPL-2.0
146222
tags: |
147-
type=ref,event=branch
148-
type=ref,event=pr
149223
type=semver,pattern={{version}}
150224
type=semver,pattern={{major}}.{{minor}}
225+
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
151226
152-
- name: Create manifest list and push
153-
working-directory: /tmp/digests
227+
- name: Sync blobs to R2
228+
env:
229+
DOCKER_RELEASE_STORAGE_BUCKET: ${{ vars.DOCKER_RELEASE_STORAGE_BUCKET }}
230+
REPO_NAME: riverqueue.com/riverproui
231+
ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }}
154232
run: |
155-
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
156-
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
233+
aws s3 cp /tmp/oci/blobs/sha256/ s3://$DOCKER_RELEASE_STORAGE_BUCKET/$REPO_NAME/blobs/sha256/ --recursive --endpoint-url $ENDPOINT_URL
157234
158-
- name: Inspect image
235+
- name: Upload manifest by digest
236+
env:
237+
DOCKER_RELEASE_STORAGE_BUCKET: ${{ vars.DOCKER_RELEASE_STORAGE_BUCKET }}
238+
REPO_NAME: riverqueue.com/riverproui
239+
ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }}
240+
run: |
241+
MANIFEST_DIGEST=$(sha256sum /tmp/oci/index.json | awk '{print $1}')
242+
aws s3 cp /tmp/oci/index.json s3://$DOCKER_RELEASE_STORAGE_BUCKET/$REPO_NAME/manifests/sha256:$MANIFEST_DIGEST --content-type "application/vnd.docker.distribution.manifest.list.v2+json" --endpoint-url $ENDPOINT_URL
243+
244+
- name: Upload tagged manifests
245+
env:
246+
DOCKER_RELEASE_STORAGE_BUCKET: ${{ vars.DOCKER_RELEASE_STORAGE_BUCKET }}
247+
REPO_NAME: riverqueue.com/riverproui
248+
ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }}
159249
run: |
160-
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
250+
TAGS=$(echo '${{ steps.meta-pro.outputs.json }}' | jq -r '.tags[] | split("/")[-1]')
251+
for TAG in $TAGS; do
252+
aws s3 cp /tmp/oci/index.json s3://$DOCKER_RELEASE_STORAGE_BUCKET/$REPO_NAME/manifests/$TAG --content-type "application/vnd.docker.distribution.manifest.list.v2+json" --endpoint-url $ENDPOINT_URL
253+
done

Dockerfile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ COPY *.go internal docs/README.md LICENSE ./
2121
COPY cmd/ cmd/
2222
COPY internal/ internal/
2323
COPY public/ public/
24+
COPY riverproui/ riverproui/
2425
COPY --from=build-ui /app/dist ./dist
2526

26-
RUN go build -o /bin/riverui ./cmd/riverui
27+
ARG BINARY=riverui
28+
RUN go build -o /bin/$BINARY ./cmd/$BINARY
2729

2830
FROM alpine:3.22.0
2931
ENV PATH_PREFIX="/"
30-
COPY --from=build-go /bin/riverui /bin/riverui
31-
CMD ["/bin/sh", "-c", "/bin/riverui -prefix=$PATH_PREFIX"]
32+
COPY --from=build-go /bin/$BINARY /bin/$BINARY
33+
CMD ["/bin/sh", "-c", "/bin/$BINARY -prefix=$PATH_PREFIX"]

Dockerfile.pro

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# syntax=docker/dockerfile:1
2+
3+
FROM node:22-alpine AS build-ui
4+
WORKDIR /app
5+
COPY package.json package-lock.json ./
6+
RUN npm install
7+
ENV NODE_ENV=production
8+
COPY . .
9+
10+
RUN npx vite build
11+
12+
# Build the Go binary, including embedded UI files:
13+
FROM golang:1.24-alpine AS build-go
14+
WORKDIR /go/src/riverui
15+
16+
COPY go.mod go.sum ./
17+
RUN go mod download
18+
19+
# Copy Go files without copying the ui dir:
20+
COPY *.go internal docs/README.md LICENSE ./
21+
COPY cmd/ cmd/
22+
COPY internal/ internal/
23+
COPY public/ public/
24+
COPY riverproui/ riverproui/
25+
COPY --from=build-ui /app/dist ./dist
26+
27+
WORKDIR /go/src/riverui/riverproui
28+
RUN go build -o /bin/riverproui ./cmd/riverproui
29+
30+
FROM alpine:3.22.0
31+
ENV PATH_PREFIX="/"
32+
COPY --from=build-go /bin/riverproui /bin/riverproui
33+
CMD ["/bin/sh", "-c", "/bin/riverproui -prefix=$PATH_PREFIX"]

0 commit comments

Comments
 (0)