Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/base-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Publish base image to GHCR

# Build the heavy esplora-base image (Bitcoin Core, Elements, electrs, libwally
# wasm, etc.) and publish it to GitHub Packages (GHCR). This is expensive, so it
# only runs when the base Dockerfile changes, or when triggered manually.
on:
push:
branches: [master]
paths:
- contrib/Dockerfile.base
- .github/workflows/base-image.yml
workflow_dispatch:

env:
REGISTRY: ghcr.io
# Publishes to ghcr.io/<owner>/esplora-base. metadata-action lowercases this.
IMAGE_NAME: ${{ github.repository_owner }}/esplora-base

jobs:
build-and-push-base:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

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

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract image metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=sha,format=long

- name: Build and push base image
uses: docker/build-push-action@v6
with:
context: .
file: contrib/Dockerfile.base
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
74 changes: 74 additions & 0 deletions .github/workflows/release-docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Publish Docker image to GHCR

# Build the esplora Docker image and publish it to GitHub Packages (GHCR)
# whenever a new GitHub Release is published. Can also be run manually
# (workflow_dispatch) for testing, with an optional override tag.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Extra image tag to push (e.g. test-build). Leave blank to only push :latest on manual runs."
required: false
default: ""

env:
REGISTRY: ghcr.io
# Publishes to ghcr.io/<owner>/<repo>. metadata-action lowercases this for us.
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

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

- name: Compute lowercase owner
id: owner
run: echo "lc=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_OUTPUT"

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract image metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Release runs derive semver tags from the release tag; manual runs
# tag :latest plus an optional caller-supplied tag.
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
type=raw,value=${{ inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' && inputs.tag != '' }}

- name: Build and push image
uses: docker/build-push-action@v6
with:
context: .
file: contrib/Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# Build on top of the GHCR base image, and stamp the built commit into
# the footer HTML (mirroring the GitLab build).
build-args: |
BASE_IMAGE=${{ env.REGISTRY }}/${{ steps.owner.outputs.lc }}/esplora-base:latest
FOOT_HTML=<!-- ${{ github.sha }} -->
# Speed up repeat builds via the GitHub Actions cache backend.
cache-from: type=gha
cache-to: type=gha,mode=max
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,31 @@ docker build -t esplora -f contrib/Dockerfile .

Alternatively, you may use the pre-built [`blockstream/esplora` image](https://hub.docker.com/r/blockstream/esplora) from Docker Hub.

## Docker images on GitHub Packages (GHCR)

In addition to Docker Hub, images are published to the GitHub Container Registry
via GitHub Actions:

- `ghcr.io/<owner>/esplora` β€” the explorer image, published on every published
GitHub Release (`.github/workflows/release-docker.yml`). Tagged with the
release version (e.g. `1.2.3`, `1.2`) and `latest`.
- `ghcr.io/<owner>/esplora-base` β€” the base image, rebuilt when
`contrib/Dockerfile.base` changes or on manual dispatch
(`.github/workflows/base-image.yml`). Tagged `latest`.

The release image builds `FROM` the GHCR base image, so on a fresh setup run the
**Publish base image to GHCR** workflow once (Actions β†’ Run workflow) before
cutting your first release. Both workflows authenticate with the built-in
`GITHUB_TOKEN`; ensure Actions has package write access (Settings β†’ Actions β†’
Workflow permissions) and set the package visibility to public if you want
anonymous pulls.

Pull the latest release image with:

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

## How to run the explorer for Bitcoin mainnet

```bash
Expand Down
5 changes: 4 additions & 1 deletion contrib/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
FROM blockstream/esplora-base:latest AS build
# Base image is overridable so CI can point at a registry-specific build
# (e.g. ghcr.io/<owner>/esplora-base) while keeping the Docker Hub default.
ARG BASE_IMAGE=blockstream/esplora-base:latest
FROM ${BASE_IMAGE} AS build

FROM debian:bookworm-slim

Expand Down