A tiny public image that lets an on-prem box pull private container images
without ever holding a static registry key. It exchanges a vlk_ API key for
a short-lived registry token from a broker endpoint, and keeps a Docker
config.json auth current so Watchtower (and the Docker CLI) can pull.
The image is public on purpose — it contains no secrets. The only credential
is the vlk_ key you supply at runtime via env; everything it fetches is
short-lived. This is the standard "ECR + Watchtower" shape: a refresher rewrites a
rotating token into the auths Watchtower reads.
vlk_ key (env) ──► POST <cloud>/v1/agent/registry-token ──► short-lived token
│
▼
writes config.json { "auths": { "<registry>": { "auth": … } } }
│
Watchtower / docker read it ──► pull private image ✓
ghcr.io/voquill/cred:latest
Multi-arch (amd64/arm64). :X.Y.Z tags track releases; :sha-… pins an exact build.
The refresher writes into a config the Watchtower container also mounts:
services:
registry-refresher:
image: ghcr.io/voquill/cred:latest # default command is `refresh`
restart: unless-stopped
environment:
VOQUILL_CLOUD_URL: https://lab-api.voquill.com
VOQUILL_API_KEY: ${REGISTRY_PULL_API_KEY} # a vlk_ key with registry:pull
VOQUILL_DOCKER_CONFIG: /config/config.json
VOQUILL_REFRESH_INTERVAL: 45m
volumes:
- ./registry-config:/config # shared, writable
watchtower:
image: nickfedor/watchtower # a maintained Watchtower fork
restart: unless-stopped
depends_on: [registry-refresher]
environment:
DOCKER_CONFIG: /config
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./registry-config:/config:ro # reads the refreshed authsThe binary is named docker-credential-voquill, so it also works as a standard
helper for docker pull / docker compose pull. Put it on PATH, set the two
env vars, and map the registry to it:
// ~/.docker/config.json
{ "credHelpers": { "us-central1-docker.pkg.dev": "voquill" } }| Var | Mode | Meaning |
|---|---|---|
VOQUILL_CLOUD_URL |
both | Base URL of the broker (the LIS). |
VOQUILL_API_KEY |
both | The site's vlk_ key carrying registry:pull. |
VOQUILL_DOCKER_CONFIG |
refresh | Path to the config.json to keep current. Default /config/config.json. |
VOQUILL_REFRESH_INTERVAL |
refresh | Refresh cadence (Go duration). Default 45m. |
The image expects POST <VOQUILL_CLOUD_URL>/v1/agent/registry-token, authed by
the vlk_ key, to return:
{ "registry": "us-central1-docker.pkg.dev", "username": "oauth2accesstoken", "token": "…", "expires_at": "…" }