Pull-through Docker Hub cache
Pull-through Docker Hub cache
A couple days ago we started hitting Docker Hub rate limits even with Docker Pro:
toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
toomanyrequests: Too Many Requests (HAP429).
Firstly we checked public.ecr.aws ↗ but the images aren’t on there yet. Docker support suggested spending $10k a year on a service account. Instead we fixed it by putting an ECR pull-through cache ↗ in front of Docker Hub. Most guides like WarpBuild’s ↗ are quite involved, and many predate ECR gaining pull-through support for Docker Hub ↗.
Our solution was simpler but not totally transparent - it required modifying our application code slightly. Sharing it here in case it’s of use, or can be improved and even integrated at some point.
- name: docker login
uses: docker/login-action@v3
with:
registry:<aws account id>.dkr.ecr.us-east-1.amazonaws.com
- name: docker mirror
if: runner.os == 'Linux'
run: |
echo '{"registry-mirrors": \["https://811169010751.dkr.ecr.us-east-1.amazonaws.com"\]}' | sudo tee /etc/docker/daemon.json > /dev/null
echo '0.0.0.0 index.docker.io registry-1.docker.io docker.io' | sudo tee -a /etc/hosts > /dev/null
sudo systemctl restart docker
# https://github.com/moby/moby/issues/30880#issuecomment-798807332
DOCKER\_CONFIG=$(jq '.auths |= . + {"https://index.docker.io/v1/": .\["811169010751.dkr.ecr.us-east-1.amazonaws.com"\]}' ~/.docker/config.json)
echo "$DOCKER\_CONFIG" > ~/.docker/config.json
We created the pull-through cache rule with the namespace “docker-hub”, added ECR perms to the configured EC2InstanceCustomPolicy, and then made 2 tweaks to our application code:
- prepend
docker-hub/to image names, - read the auth token from
~/.docker/config.jsonto pass to the/images/createAPI call. Most libraries do this automatically but not the Rust one we use yet ↗. Thedockercli also does this automatically.
Last updated: December 4, 2025