Setting up a caching proxy for docker
Docker recently set rate limits for the number of images that can be pulled from Docker Hub per IP address. This generally won't matter much as your local docker daemon keeps a cache of images it pulls. But if you have multiple people working behind one internet connection or even just multiple computers that do docker based builds, you could run into the limits. The solution to this is to use a caching proxy to access docker hub. This can be done with the freely available Docker registry. My preferred way to do this would be to just run a service under systemD, but it appears the method of distribution for docker registry is actually just a docker container. I have a computer running on my network that I can use for this purpose.
After some experimentation I figured out that the registry needs to be pointed at a hostname of https://registry-1.docker.io
. This can be done with the following configuration file
I saved this file to my home directory. The container's usual configuration file is at /etc/docker/registry/config.yml
so it can be overridden when creating the container
docker run -d --restart always --name mirror -v $HOME/mirror.json:/etc/docker/registry/config.yml -p 5000:5000 registry:2.8.3
This starts the registry container and exposes the service on port 5000 of the host machine. At this point I need my local workstation to point at my mirror. So I edited my local /etc/docker/daemon.json
to have
{ "registry-mirrors":["http://vworkstation.home.hydrogen18.com:5000"], "max-download-attempts":1 }
You need to set the registry mirror to be the hostname of the machine you are running the docker container on. With the configuration updated I did sudo systemctl restart docker
to have the docker daemon pick up the change. I then ran the following to make sure things still worked on my workstation
$ docker run --rm -it debian:bookworm /bin/sh Unable to find image 'debian:bookworm' locally bookworm: Pulling from library/debian 7cd785773db4: Pull complete Digest: sha256:18023f131f52fc3ea21973cabffe0b216c60b417fd2478e94d9d59981ebba6af Status: Downloaded newer image for debian:bookworm #
Back on the host that runs the mirror you can do docker logs mirror
. You can see it is caching data when you see logs like this show up
192.168.165.6 - - [03/Apr/2025:02:47:06 +0000] "GET /v2/library/debian/blobs/sha256:d844481994701734800e3e8708049b9585d1b81472f9856157fe17e45ab11f7a HTTP/1.1" 200 453 "" "docker/27.3.1 go/go1.22.7 git-commit/41ca978 kernel/6.8.0-55-generic os/linux arch/amd64 UpstreamClient(Docker-Client/27.3.1 \\(linux\\))" time="2025-04-03T02:47:06.851126657Z" level=info msg="response completed" go.version=go1.20.8 http.request.host="vworkstation.home.hydrogen18.com:5000" http.request.id=676c54db-4318-4503-9111-e641f9762c62 http.request.method=GET http.request.remoteaddr="192.168.165.6:56496" http.request.uri="/v2/library/debian/blobs/sha256:d844481994701734800e3e8708049b9585d1b81472f9856157fe17e45ab11f7a" http.request.useragent="docker/27.3.1 go/go1.22.7 git-commit/41ca978 kernel/6.8.0-55-generic os/linux arch/amd64 UpstreamClient(Docker-Client/27.3.1 \(linux\))" http.response.contenttype="application/octet-stream" http.response.duration=390.348935ms http.response.status=200 http.response.written=453