-
-
Notifications
You must be signed in to change notification settings - Fork 271
Automate publishing multiarch images to GHCR (migrate away from Docker Hub) #395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
0c1bb67
docker: Build AMD64+ARM64 multiarch images and push to GHCR.
klardotsh 2627d65
docker: Link GHCR to this Git repository.
klardotsh fd4ef60
k8s: Point to GHCR image paths and version bump.
klardotsh 5328986
docs: README updated to reflect new paths and versions.
klardotsh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
on: | ||
workflow_call: | ||
inputs: | ||
# N.B.: This behavior is not concurrency-safe and updates the mutable | ||
# :latest image tag | ||
push-latest: | ||
type: boolean | ||
primary-registry-tag: | ||
type: string | ||
skip-pull-check: | ||
type: boolean | ||
|
||
jobs: | ||
multiarch-image: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
packages: write | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@v2 | ||
- name: Set up Docker Buildx | ||
id: buildx | ||
uses: docker/setup-buildx-action@v2 | ||
- name: Login to GitHub Container Registry | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.repository_owner }} | ||
password: ${{ github.token }} | ||
- name: Set PUSH_LATEST_TAG in environment | ||
if: inputs.push-latest | ||
run: echo "PUSH_LATEST_TAG=1" >> $GITHUB_ENV | ||
- name: Set REGISTRY_TAG in environment | ||
if: inputs.primary-registry-tag != '' | ||
run: echo "REGISTRY_TAG=${{ inputs.primary-registry-tag }}" >> $GITHUB_ENV | ||
- name: Set SKIP_PULL_CHECK in environment | ||
if: inputs.skip-pull-check | ||
run: echo "SKIP_PULL_CHECK=1" >> $GITHUB_ENV | ||
- name: Build Images | ||
env: | ||
EXTERNAL_QEMU: "1" | ||
run: ./build_and_push_image.sh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
name: Publish Docker Image to GHCR (versioned + :latest) | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
multiarch-image: | ||
uses: ./.github/workflows/build-and-push-ghcr-common.yml | ||
secrets: inherit | ||
permissions: | ||
packages: write | ||
with: | ||
push-latest-tag: true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
name: Publish Docker Image to GHCR (PR) | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
multiarch-image: | ||
uses: ./.github/workflows/build-and-push-ghcr-common.yml | ||
secrets: inherit | ||
permissions: | ||
packages: write | ||
with: | ||
# dz prefix to emphasize that the commit does not line up with any commit | ||
# in zulip/zulip | ||
primary-registry-tag: "dz-${{ github.sha }}" | ||
# There's no realistic chance of overwriting an existing SHA tag here, so | ||
# save the pull time | ||
skip-pull-check: true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# This should ~always be updated to match the Zulip Server version targeted, | ||
# with the trailing -N used to denote image versions within the series. Only | ||
# the final line of this file is read during publishing. | ||
# | ||
# Note that changes to the Dockerfile that are not bundled with a bump to this | ||
# number will never be published to GitHub Container Registry, as duplicates | ||
# aren't built. | ||
|
||
# Changelog: | ||
# | ||
# 6.1-1: Add ARM64 support, publish to GHCR | ||
# <--> This file created here <--> | ||
# 6.1-0: final version published exclusively to Docker Hub | ||
|
||
6.1-1 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This script wraps Docker and Docker BuildX to build multiarch Zulip images. | ||
# Make sure a recent Docker and BuildX are installed on your system - Docker | ||
# Desktop users (on any OS) should be good to go, those using Linux | ||
# distribution's builds of Docker will need to find the correct packages. | ||
# | ||
# To use locally, override the environment variables REGISTRY, REGISTRY_TAG | ||
# (perhaps to 'local'), and optionally BUILDX_PLATFORMS. Additionally, | ||
# PUSH_LATEST_TAG can be set to 1 to additonally tag :latest when pushing to | ||
# the registry. Then, run the script without arguments. For example: | ||
# | ||
# REGISTRY=docker.example.com/myorg/zulip REGISTRY_TAG=local PUSH_LATEST_TAG=1 | ||
# ./build_and_push_image.sh | ||
# | ||
# Note: EXTERNAL_QEMU=1 is required when it's unsafe or undesired to manage | ||
# binfmt helpers, for example within CI systems like GitHub Actions (use | ||
# docker/setup-buildx-action@v1 instead). | ||
# | ||
# By default, REGISTRY:REGISTRY_TAG will be built for linux/amd64 and | ||
# linux/arm64. Adding other platforms to this list is unsupported and will | ||
# almost certainly not work, but the list can be shrunk. REGISTRY must be set | ||
# to something the builder has push access to, because BuildX images and | ||
# manifests are not loaded into the host's Docker registry (an upstream | ||
# limitation). | ||
# | ||
# If building for architectures other than that the host runs on, ne can expect | ||
# this step to take many multiples of the time it takes to build the Zulip | ||
# image for just the native architecture. If it takes 10 minutes to build the | ||
# amd64 image by itself, expect cross-compiling the arm64 image to take 30-60 | ||
# minutes on most currently-common hardware. Currently, distributing the image | ||
# builds to multiple machines (perhaps to allow the arm64 image to build on a | ||
# native arm64 host for efficiency) is unsupported. | ||
# | ||
# Assuming all goes well, REGISTRY:REGISTRY_TAG will point to a multiarch | ||
# manifest referring to an image for each of BUILDX_PLATFORMS, which can then | ||
# be rolled out to your infrastructure, used in Docker Compose, etc. | ||
# | ||
# Please report bugs with this script or anything it runs, or with running | ||
# Zulip on arm64 in general, at https://github.com/zulip/docker-zulip and/or at | ||
# https://chat.zulip.org | ||
|
||
set -ex | ||
|
||
REGISTRY="${REGISTRY:-ghcr.io/zulip/zulip}" | ||
REGISTRY_TAG="${REGISTRY_TAG:-$(tail -n 1 < "$(git rev-parse --show-toplevel)/IMAGE_TAG")}" | ||
PRIMARY_IMAGE="${REGISTRY}:${REGISTRY_TAG}" | ||
|
||
if [ "${SKIP_PULL_CHECK}" != "1" ]; then | ||
if docker pull "${PRIMARY_IMAGE}"; then | ||
echo "Image ${PRIMARY_IMAGE} already exists, refusing to overwrite!" > /dev/stderr | ||
exit 1 | ||
fi | ||
fi | ||
|
||
PUSH_LATEST_TAG="${PUSH_LATEST_TAG:-0}" | ||
|
||
if [ "${PUSH_LATEST_TAG}" = "1" ]; then | ||
PUSH_LATEST_TAG_ARG=("-t" "${REGISTRY}:latest") | ||
fi | ||
|
||
# Default to creating our own buildx context, as "default", using the native | ||
# "docker" driver, can result in errors like the following when using Linux | ||
# distros' Docker and not Docker Desktop: | ||
# | ||
# ERROR: multiple platforms feature is currently not supported for docker | ||
# driver. Please switch to a different driver (eg. "docker buildx create | ||
# --use") | ||
BUILDX_BUILDER="${BUILDX_BUILDER:-zulip}" | ||
BUILDX_PLATFORMS="${BUILDX_PLATFORMS:-linux/amd64,linux/arm64}" | ||
|
||
if [ "${EXTERNAL_QEMU}" != "1" ]; then | ||
# --credential yes is required to run sudo within qemu, without it the | ||
# effective UID after a call to sudo will not be 0 and sudo in cross-built | ||
# containers (eg. the arm64 build if running on an amd64 host) will fail. | ||
# See also: https://github.com/crazy-max/ghaction-docker-buildx/issues/213. | ||
# | ||
# We're allowing failures here (|| true) for two main reasons: | ||
# | ||
# - BUILDX_PLATFORMS can be overridden to a single, native platform | ||
# (meaning this QEMU reset won't be necessary anyway) | ||
# - On ZFS<2.2 root filesystems, this incantation can fail due to | ||
# Docker-side dataset teardown issues as documented in | ||
# https://github.com/moby/moby/issues/40132. The QEMU reset may have | ||
# succeeded despite the Docker daemon errors, so we'll try to power | ||
# through. | ||
docker run \ | ||
--rm \ | ||
--privileged \ | ||
multiarch/qemu-user-static \ | ||
--reset \ | ||
-p yes \ | ||
--credential yes \ | ||
|| true | ||
fi | ||
|
||
(docker buildx ls | grep "${BUILDX_BUILDER}" >/dev/null 2>&1) || { | ||
docker buildx create \ | ||
--name "${BUILDX_BUILDER}" \ | ||
--platform "${BUILDX_PLATFORMS}" \ | ||
--bootstrap \ | ||
--use | ||
} | ||
|
||
docker buildx build \ | ||
--platform "${BUILDX_PLATFORMS}" \ | ||
-t "${PRIMARY_IMAGE}" \ | ||
"${PUSH_LATEST_TAG_ARG[@]}" \ | ||
--push \ | ||
. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think it’s worthwhile to maintain an extra changelog when we already have Git.
Can we have things trigger based on the names of Git tags pushed to the repository, rather than maintaining this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, we can definitely do that easily in GHA. The only tradeoff is "how automatic will this be?" - as authored, as soon as this file changes in
main
, a new GHCR tag is cut, meaning 0 human interaction required post-merge to get Docker image changes published. The tag method is 1 (small) interaction that - so long as the same naming scheme is followed - comes with no other tradeoffs I can think of.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Editing a file is an interaction too. We want the Git tags to be there anyway; they’re self-documenting, more flexible (e.g. we could push a tag that isn’t on
main
for an emergency patch release), more standard, and simpler. So I think we should go with that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm yeah the non-main case seems especially useful of an addition here. I'll patch this up.