docker-registry-proxy is a pull-through cache for various container registries, primarily focused on docker images.
See also:
Getting this stood up took some trial and error, and very careful reading of the repository readme. Particular pain points:
- Only the
latest-debugimage worked for me - Pay close attention in the
HTTPS_PROXYenviron – the URL is still plain HTTP, not HTTPS! - After setting up the proxy, run
sudo docker system prune -a -fto clear all of Docker’s caches. Until then, I was getting errors that looked like DNS resolution.
Additionally, I had to set up custom DNS settings for this container. Add a volume to override the NGINX resolvers.conf:
docker-registry-proxy:
container_name: docker_registry_proxy
image: rpardini/docker-registry-proxy:latest-debug
restart: unless-stopped
ports:
- 8012:3128
# To enable debugging (DO NOT DO THIS IN PRODUCTION):
# - 8013:8081 # Displays mitmproxy interface for incoming traffic
# - 8014:8082 # Displays mitmproxy interface for outgoing traffic
volumes:
- /mnt/nas_pool/docker_reg/pullthru:/docker_mirror_cache
- /opt/docker/docker-registry-proxy/ca:/ca
- /opt/docker/docker-registry-proxy/nginx-resolver-conf:/etc/nginx/resolvers.conf
environment:
# Enable the pull-thru cache
ENABLE_MANIFEST_CACHE: true
# Max cache size
CACHE_MAX_SIZE: 32g
# Turned off while troubleshooting. Does what it says on the tin.
DISABLE_IPV6: trueand then in the /opt/docker/docker-registry-proxy/nginx-resolver-conf file:
resolver 192.168.30.142 ipv6=off;
I’m not sure if the semicolon is needed there, but it worked, so I haven’t touched it.
Client setup
It’s not trivial to set up a system to use this proxy, and although it’s all there in the README, it’s a little scattered.
- Create (if not already exists)
/etc/systemd/system/docker.service.d - Add a file in that directory; I’ll call it
pullthru-cache.confwith the following. The trailing slash is important.[Service] Environment="HTTP_PROXY=http://<server>:<port>/" Environment="HTTPS_PROXY=http://<server>:<port>/" - Pull down the CA certificate from the proxy server:
curl http://<server>:<port>/ca.crt | sudo tee /usr/share/ca-certificates/docker-registry-proxy.crt - Add the certificate to … some important config:
sudo vim /etc/ca-certificates.confand add/usr/share/ca-certificates/docker-registry-proxy.crtto the end of it - Update certificates:
sudo update-ca-certificates --fresh - Reload systemd to include the new docker configs:
sudo systemctl daemon-reload - Restart docker to apply:
sudo systemctl restart docker.service
At this point, it should be working. Test it by pulling an image, like sudo docker pull sphinxdoc/sphinx.
Recovering from failures
If the server breaks for any reason, this client will now be unable to pull docker images. This gets especially hairy when it’s the host running this proxy that’s now unable to pull images (say, to fix the problem). To bypass the proxy, comment out that systemd file, do a
sudo systemctl daemon-reload, and then restart docker (sudo systemctl restart docker.service) and now pulling images will go straight to the real registry.
See also:
- Docker systemd unit file docs: https://docs.docker.com/engine/daemon/proxy/#systemd-unit-file
- The plain-docker-registry way to do… approximately this: https://stackoverflow.com/questions/28557384/docker-private-registry-with-mirror This approach only mirrors the docker hub; while the docker-registry-proxy container also gets some other registries (GHCR, Quay, etc)
Clearing the cache
Sometimes, you may want to induce a clearing of the cache to fetch new images. I don’t know of an official way to do this, but you can simply go to the directory you mapped to docker_mirror_cache (per the above example, /mnt/nas_pool/docker_reg/pullthru) and delete all the contents therein. Then, run the typical docker update process.