Azure Container Registry Cache: Updated Guide with Docker Hub Integration
Some time ago, I wrote an article about Docker Hub rate limits and described ways to mitigate them. Unfortunately, the method I suggested using Azure Container Registry cache no longer works without authentication.
You can find more details about this in the Artifact cache in Azure Container Registry documentation, specifically in the Upstream support section.
Azure Container Registry supports only authenticated pulls to Docker Hub.
How to Enable Caching, the correct way
Let me walk you through enabling the cache. Here are the steps:
- Create a free Docker Hub account if you don't have one yet
- Create a personal access token in Docker Hub
- Store your Docker Hub username and token credentials in Azure KeyVault
- Create an Azure Container Registry credential cache to retrieve the KeyVault credentials for Docker Hub
- Create an Azure Container Registry caching rule using that credential set
To simplify this process, I've created a GitHub repository with all the necessary automation.
Bicep Automation
The GitHub repository uses Bicep to automate resource creation in Azure. Before running it, you'll need a personal access token from Docker Hub.
Feel free to choose access permissions that make sense for your needs. Since I'm only working with public repositories, I selected that option.
Example Deployment
To test this, you can either export the variables DOCKER_HUB_USERNAME
and DOCKER_HUB_PAT
and run the deploy.sh
script, or modify the src/main.bicepparam
file.
The credentials will be stored in a newly created Azure KeyVault within the example resource group. You can modify the resource group name and location in the parameter file.
After deployment, you can link your public Docker Hub repository to Azure Container Registry by creating a cache with the credentials set from the Bicep deployment.
For example, to cache the public Python repository, you can
Once the cache rule is created we can evaluate it in the Azure Portal
To pull new images, simply reference your Azure Container Registry repository wherever you need it—whether in Azure Pipelines, GitHub Actions, or directly in the shell like
❯ az acr login --name acrdemoxtpogsljytqrc
Login Succeeded
~ took 5s
❯ docker pull acrdemoxtpogsljytqrc.azurecr.io/python
Using default tag: latest
latest: Pulling from python
Digest: sha256:d57ec66c94b9497b9f3c66f6cdddc1e4e0bad4c584397e0b57a721baef0e6fdc
Status: Image is up to date for acrdemoxtpogsljytqrc.azurecr.io/python:latest
acrdemoxtpogsljytqrc.azurecr.io/python:latest
~
❯ docker pull acrdemoxtpogsljytqrc.azurecr.io/python:alpine3.20
alpine3.20: Pulling from python
c4f340f38ec0: Download complete
0152682790bb: Download complete
bb4d68a0c460: Download complete
05da92a20133: Download complete
Digest: sha256:9ab3b6ef4afb7582afaa84e97d40a36f192595bb0578561c282cecc22a45de49
Status: Downloaded newer image for acrdemoxtpogsljytqrc.azurecr.io/python:alpine3.20
acrdemoxtpogsljytqrc.azurecr.io/python:alpine3.20
Thanks to the cache rule, the images automatically transfer to your Azure Container Registry and appear in your ACR repository.
Notes
In the shared GitHub project, I use a system-assigned identity, which requires splitting KeyVault creation and KeyVault Access Policies. This setup can be simplified once the corresponding issue is resolved to allow user-assigned managed identities.
I hope this helps!