Skip to content

Commit c2e6938

Browse files
authored
ci: publish Docker images to GHCR alongside Docker Hub (#7569)
* ci: publish Docker images to GHCR alongside Docker Hub Adds ghcr.io/ether/etherpad as a second publish target on release tags, reusing the existing docker/metadata-action step so the same SemVer tags (e.g. 2.6.1, 2.6, 2, latest) are pushed to both registries. Motivation: downstream consumers (Helm charts in particular) hit Docker Hub anonymous pull rate limits. GHCR has no such limits and the workflow already runs with GITHUB_TOKEN, so this is additive with no new secrets required. Docker Hub remains the primary/canonical source; GHCR is a mirror. Note: this only affects future release tags. The 2.6.1 tag already on Docker Hub will need to be mirrored separately (e.g. via skopeo) if downstream needs it on GHCR before the next release. * address qodo review: scope packages:write to publish job, document GHCR Two fixes from the qodo code review on #7569: 1. Overprivileged PR token (security). The original change set 'packages: write' at workflow level, which meant pull_request runs (whose Test step executes PR-controlled code) also inherited push access to GHCR. Splits the workflow into two jobs: - build-test: runs on pull_request and push with contents:read only. Does the single-arch load+test as before. - publish: needs build-test, runs only on push with packages:write. Does the multi-arch build-and-push, Docker Hub description update, and ether-charts bump. Docker Hub login is also now gated by job-level 'if' (same effect as the previous step-level 'if'). 2. Docs miss GHCR option. Updates doc/docker.md and README.md to document the GHCR mirror alongside Docker Hub with equivalent pull examples, so downstream users discovering via docs can choose the mirror to avoid Docker Hub rate limits.
1 parent 3ccf0b1 commit c2e6938

3 files changed

Lines changed: 52 additions & 19 deletions

File tree

.github/workflows/docker.yml

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ on:
1212
- 'v?[0-9]+.[0-9]+.[0-9]+'
1313
env:
1414
TEST_TAG: etherpad/etherpad:test
15+
1516
permissions:
1617
contents: read
1718

1819
jobs:
19-
docker:
20+
build-test:
2021
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
2124
env:
2225
PNPM_HOME: ~/.pnpm-store
2326
steps:
@@ -26,11 +29,6 @@ jobs:
2629
uses: actions/checkout@v6
2730
with:
2831
path: etherpad
29-
30-
-
31-
name: Set up QEMU
32-
if: github.event_name == 'push'
33-
uses: docker/setup-qemu-action@v4
3432
-
3533
name: Set up Docker Buildx
3634
uses: docker/setup-buildx-action@v4
@@ -78,29 +76,55 @@ jobs:
7876
done
7977
(cd src && gnpm run test-container)
8078
git clean -dxf .
79+
80+
publish:
81+
needs: build-test
82+
if: github.event_name == 'push'
83+
runs-on: ubuntu-latest
84+
permissions:
85+
contents: read
86+
packages: write
87+
steps:
88+
-
89+
name: Check out
90+
uses: actions/checkout@v6
91+
with:
92+
path: etherpad
93+
-
94+
name: Set up QEMU
95+
uses: docker/setup-qemu-action@v4
96+
-
97+
name: Set up Docker Buildx
98+
uses: docker/setup-buildx-action@v4
8199
-
82100
name: Docker meta
83-
if: github.event_name == 'push'
84101
id: meta
85102
uses: docker/metadata-action@v6
86103
with:
87-
images: etherpad/etherpad
104+
images: |
105+
etherpad/etherpad
106+
ghcr.io/ether/etherpad
88107
tags: |
89108
type=ref,event=branch
90109
type=semver,pattern={{version}}
91110
type=semver,pattern={{major}}.{{minor}}
92111
type=semver,pattern={{major}}
93112
-
94113
name: Log in to Docker Hub
95-
if: github.event_name == 'push'
96114
uses: docker/login-action@v4
97115
with:
98116
username: ${{ secrets.DOCKERHUB_USERNAME }}
99117
password: ${{ secrets.DOCKERHUB_TOKEN }}
118+
-
119+
name: Log in to GHCR
120+
uses: docker/login-action@v4
121+
with:
122+
registry: ghcr.io
123+
username: ${{ github.actor }}
124+
password: ${{ secrets.GITHUB_TOKEN }}
100125
-
101126
name: Build and push
102127
id: build-docker
103-
if: github.event_name == 'push'
104128
uses: docker/build-push-action@v7
105129
with:
106130
context: ./etherpad
@@ -109,6 +133,7 @@ jobs:
109133
push: true
110134
tags: ${{ steps.meta.outputs.tags }}
111135
labels: ${{ steps.meta.outputs.labels }}
136+
cache-from: type=gha
112137
- name: Update repo description
113138
uses: peter-evans/dockerhub-description@v5
114139
if: github.ref == 'refs/heads/master'
@@ -118,8 +143,8 @@ jobs:
118143
password: ${{ secrets.DOCKERHUB_TOKEN }}
119144
repository: etherpad/etherpad
120145
enable-url-completion: true
121-
- name: Check out
122-
if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
146+
- name: Check out ether-charts
147+
if: github.ref == 'refs/heads/develop'
123148
uses: actions/checkout@v6
124149
with:
125150
path: ether-charts

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,13 @@ $env:ETHERPAD_RUN=1; irm https://raw.githubusercontent.com/ether/etherpad/master
103103

104104
### Docker-Compose
105105

106+
The official image is published to both Docker Hub (`etherpad/etherpad`) and GitHub Container Registry (`ghcr.io/ether/etherpad`) with identical tags. Use whichever suits your environment; GHCR avoids Docker Hub's anonymous pull rate limits.
107+
106108
```yaml
107109
services:
108110
app:
109111
user: "0:0"
110-
image: etherpad/etherpad:latest
112+
image: etherpad/etherpad:latest # or: ghcr.io/ether/etherpad:latest
111113
tty: true
112114
stdin_open: true
113115
volumes:

doc/docker.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
# Docker
22

3-
The official Docker image is available on https://hub.docker.com/r/etherpad/etherpad.
3+
The official Docker image is published to two registries with identical tags:
44

5-
## Downloading from Docker Hub
6-
If you are ok downloading a [prebuilt image from Docker Hub](https://hub.docker.com/r/etherpad/etherpad), these are the commands:
5+
- Docker Hub (canonical): https://hub.docker.com/r/etherpad/etherpad
6+
- GitHub Container Registry (mirror): https://github.com/ether/etherpad/pkgs/container/etherpad
7+
8+
The GHCR mirror is useful if you are hitting Docker Hub anonymous pull rate limits (for example on Kubernetes clusters).
9+
10+
## Downloading a prebuilt image
711
```bash
8-
# gets the latest published version
12+
# from Docker Hub
913
docker pull etherpad/etherpad
10-
11-
# gets a specific version
1214
docker pull etherpad/etherpad:2.6.1
15+
16+
# from GHCR (same image, same tags)
17+
docker pull ghcr.io/ether/etherpad
18+
docker pull ghcr.io/ether/etherpad:2.6.1
1319
```
1420

1521
## Build a personalized container

0 commit comments

Comments
 (0)