Skip to content

Publish Docker images to GitHub Packages (GHCR) - #629

Closed
mbukeRepo wants to merge 3 commits into
Blockstream:masterfrom
mbukeRepo:feat/push-images-to-ghcr
Closed

Publish Docker images to GitHub Packages (GHCR)#629
mbukeRepo wants to merge 3 commits into
Blockstream:masterfrom
mbukeRepo:feat/push-images-to-ghcr

Conversation

@mbukeRepo

@mbukeRepo mbukeRepo commented Jun 18, 2026

Copy link
Copy Markdown

📦 Publish Docker images to GitHub Packages (GHCR)

This PR sets up automated Docker image publishing to the GitHub Container
Registry
so that every release produces a versioned, immutable image — straight
from GitHub, with zero extra secrets to manage.

Why this is worth it

Today our images are built by GitLab CI and only ever pushed as :latest. There's
no way to pull "the image for release 1.2.3" — which makes rollbacks, reproducible
deploys, and pinning painful. This PR fixes exactly that, while leaving the existing
Docker Hub pipeline completely untouched.

What's included

  • release-docker.yml — on a published GitHub Release (or a manual run), builds
    the esplora image and pushes ghcr.io/<owner>/esplora tagged 1.2.3, 1.2, and
    latest. Manual runs accept an optional extra tag for testing.
  • base-image.yml — builds and publishes ghcr.io/<owner>/esplora-base when
    contrib/Dockerfile.base changes, or on demand. (It's a heavy build, so it only
    runs when it actually needs to.)
  • contrib/Dockerfile — adds ARG BASE_IMAGE so CI can build on top of the GHCR
    base, defaulting to blockstream/esplora-base:latest so nothing else changes.
  • README — a new "Docker images on GitHub Packages (GHCR)" section covering tags,
    usage, and setup.

🔑 One-time setup (please do this before merging-to-release)

  1. Settings → Actions → Workflow permissions → enable Read and write.
  2. After merge, run Actions → "Publish base image to GHCR" → Run workflow once
    (the release image builds FROM the GHCR base, so it needs to exist first).
  3. Publish a Release — the versioned image lands in GHCR automatically. 🎉
  4. (Optional) Flip the package visibility to public if you want anonymous pulls.

✅ Safe by design

  • Built-in GITHUB_TOKEN only — no new secrets.
  • The existing GitLab → Docker Hub pipeline is 100% unchanged.
  • amd64 only for now (fast, reliable on GitHub-hosted runners); arm64 is a one-line
    add later if we want it.

Pull it once it's live:

docker pull ghcr.io/<owner>/esplora:latest

Publish container images to GitHub Packages (GHCR) alongside the existing
Docker Hub builds, giving us versioned, release-pinned images we don't have
today.
Comment thread .github/workflows/base-image.yml Outdated
Comment thread .github/workflows/release-docker.yml Outdated
@mbukeRepo
mbukeRepo force-pushed the feat/push-images-to-ghcr branch from 68b9eba to e2fb761 Compare August 21, 2026 20:19
@mbukeRepo
mbukeRepo requested a review from Randy808 August 22, 2026 14:21
@DeviaVir

Copy link
Copy Markdown
Contributor

Hi @mbukeRepo, thank you for the well-prepared PR and for flagging a real gap: there was no way to pull a pinnable, versioned esplora image.

We've decided to solve it in the pipeline that already builds, tests, and publishes our images instead of adding a second publishing channel: #661 makes our existing CI publish versioned Docker Hub tags (e.g. blockstream/esplora:v2.10) from our release tags, next to :latest.

A few reasons we went that way rather than merging this one:

  • The release: published trigger would never fire here, this repo uses git tags (esplora_vX.YY), not GitHub Releases, so the semver patterns wouldn't match our tag format either.
  • A second "official" image channel (GHCR) built outside our normal pipeline creates a supply-chain and consistency surface we'd have to maintain: the GHCR base image would need manual dispatches to stay in sync, and users couldn't tell which channel is canonical.
  • The setup requires widening the default workflow token permissions repo-wide, which we'd rather avoid given the existing pull_request_target workflow.

Since #661 covers the underlying need with one registry and no new secrets, I'm closing this PR. Thanks again for the contribution and for the clear write-up - it's what prompted us to fix the versioning gap.

@DeviaVir DeviaVir closed this Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants