registry-proxy init source
A pull-through cache for Docker Hub, as required by conventional/container-images.md. With it in front, builds and CI keep working when Docker Hub is down or throttling, and every image is fetched from Docker Hub once rather than once per job.
Contents
| File | What it is |
|---|---|
docker-compose.yml | The proxy: registry:3.1.1 in proxy mode, pinned by digest |
Deploying (host owner)
On the registry host (10.0.0.106):
Copy this directory to the host.
Optional: create
.envnext todocker-compose.ymlwith Docker Hub credentials, which raise the pull limit. Use a read-only access token, never a password, and never commit the file:REGISTRY_PROXY_USERNAME=<docker hub user> REGISTRY_PROXY_PASSWORD=<read-only access token>Start it:
bashdocker compose up -dCheck that it answers for an official image. Official images live under
library/; a barepostgresis not found:bashcurl -s -o /dev/null -w '%{http_code}\n' \ -H 'Accept: application/vnd.oci.image.index.v1+json' \ http://10.0.0.106:5001/v2/library/postgres/manifests/18.6-trixie # 200
It is a second registry, next to the one on port 5000, because a registry in proxy mode refuses pushes: the same instance cannot be both our push target and a mirror.
Pointing a Docker host at it
On each workstation and on the CI runner - the integration jobs use the runner's own Docker daemon - add the proxy to /etc/docker/daemon.json, keeping whatever is already there:
{
"registry-mirrors": ["http://10.0.0.106:5001"],
"insecure-registries": ["10.0.0.106:5000", "10.0.0.106:5001"]
}Then sudo systemctl restart docker, and check that docker info lists it under Registry Mirrors. Image names in the repositories do not change, and Docker falls back to Docker Hub when the proxy is down.
Confirming a pull went through it
A mirror that is configured but bypassed looks exactly like one that works, so check once per host:
docker pull redis:8.8.2-trixie
curl -s http://10.0.0.106:5001/v2/_catalog
# {"repositories":["library/redis", ...]}If the repository does not appear, the daemon went straight to Docker Hub - fix that before relying on the proxy.
Where the daemon cannot be configured
Docker-in-docker, or a runtime other than Docker: name the proxy in the image, with the library/ segment for official images:
registry:5001/library/postgres:18.6-trixieFor testcontainers, set the prefix and write official images with library/:
export TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX=registry:5001Image: "library/postgres:18.6-trixie",testcontainers adds the prefix only to Docker Hub names and never adds library/ itself, which is why the image has to carry it.