Nightly mirror of Docker Hardened Images from dhi.io to ghcr.io/fabro-sh/*.
DHI requires an authenticated pull against a subscription account. Mirroring to GHCR lets downstream repos (e.g. fabro-sh/fabro) pull from a namespace they already have access to, without each workflow needing DHI credentials.
| Source (dhi.io) | Destination (ghcr.io) |
|---|---|
dhi.io/alpine-base:3.23-dev |
ghcr.io/fabro-sh/dhi-alpine-base:3.23-dev |
dhi.io/alpine-base:3.23 |
ghcr.io/fabro-sh/dhi-alpine-base:3.23 |
Each source tag is mirrored with two destination tags:
<tag>— moves with every nightly run, always points at the latest mirrored digest.<tag>-YYYY-MM-DD— immutable, dated pin for reproducible builds.
Moving tag (auto-updates on nightly run):
FROM ghcr.io/fabro-sh/dhi-alpine-base:3.23-devDated pin (immutable):
FROM ghcr.io/fabro-sh/dhi-alpine-base:3.23-dev-2026-04-18For strict reproducibility, pin by digest:
docker buildx imagetools inspect ghcr.io/fabro-sh/dhi-alpine-base:3.23-dev \
--format '{{json .Manifest.Digest}}'Runs nightly at 07:00 UTC via .github/workflows/mirror.yml. Can also be triggered manually via workflow_dispatch.
The workflow needs two secrets configured on this repo:
DHI_USERNAME— Docker Hub username with DHI subscription accessDHI_TOKEN— Docker Hub access token for that account
GHCR push uses GITHUB_TOKEN (automatic).
Edit the matrix.image list in .github/workflows/mirror.yml. Each entry is { source, repo, tag }. Use the dhi-<family> naming convention for the destination repo.
The workflow uses docker buildx imagetools create to copy the multi-arch manifest list from dhi.io to ghcr.io without pulling layers through the runner — the registries handle the blob transfer directly.