Azure Container Registry: Build, Store, Version, Manage
Where every container image you ship to production lives. ACR tiers, repositories, tags, content trust, geo-replication, and how managed identity replaces admin credentials.
What ACR actually does
Azure Container Registry is a private library for your container images. Docker Hub is a public library β anyone can read most of it. ACR is yours: you push your AI inference image, your front-end image, your worker image β they sit in your subscription, behind your network rules, with your access policies.
An ACR has repositories (one per app, like roo-vision) and inside each repository, tags mark versions (:v3.4.1, :latest). When App Service or Container Apps starts your app, it pulls the right tag from ACR.
The exam expects you to know how to push images, how to version them sensibly, how to let Azure compute services pull them without secrets, and which ACR tier supports which features.
ACR SKUs β which tier to pick
| Feature | Basic | Standard | Premium |
|---|---|---|---|
| Storage | 10 GB | 100 GB | 500 GB included, scales further |
| Webhooks per registry | 2 | 10 | 500 |
| Geo-replication | No | No | Yes β replicate to any Azure region |
| Content trust (image signing) | No | No | Yes (Notation v2 / Notary) |
| Private endpoints / VNet | No | No | Yes |
| Customer-managed keys | No | No | Yes |
| Best for | Dev sandboxes, demos | Most production workloads (single region) | Multi-region, regulated, supply-chain hardened |
Exam tip: 'geo-replication' = Premium
Whenever a question mentions βlow-latency pulls in multiple Azure regionsβ or βthe registry must be available in another region for failoverβ, the answer involves ACR Premium. Standard cannot replicate. This is one of the most common single-fact gotchas in container questions.
Tags, digests, and how to version sensibly
A tag is a human-readable pointer; a digest is a cryptographic hash. The same image can have many tags pointing to it, but exactly one digest.
# Same image, two views:
roo-vision:v3.4.1
roo-vision@sha256:7e2b1c... # immutable digest
| Practice | Why |
|---|---|
Push every release as a unique semver tag (:v3.4.1) | Lets you pin and roll back without ambiguity |
Also push :latest | Convenient for dev, but never rely on it in production manifests |
| Pin production deployments by digest | A tag can be reassigned; a digest cannot. Eliminates βbut it worked yesterdayβ |
Lock images with az acr repository update --image roo-vision:v3.4.1 --write-enabled false | Prevents the tag from being overwritten |
Real-world example: Theo locks audited builds
Tidewater Healthβs compliance team must be able to prove that the inference image running today is the same one the security team scanned six weeks ago.
Theoβs pipeline:
- ACR Tasks builds the image and tags it
:v2.7.0and the SHA digest is recorded. - The security scan runs against
tidewater-rag@sha256:abc...(digest). - After approval, Theo runs
az acr repository update --image tidewater-rag:v2.7.0 --write-enabled falseβ the tag is now immutable. - AKS manifests reference the digest, not the tag. Future image rebuilds cannot silently replace whatβs running.
Authenticating to ACR β the four options
| Method | When to use | Notes |
|---|---|---|
| Microsoft Entra ID user / service principal | CI/CD pipelines, individual developers | Use az acr login β uses your Entra token, no admin password |
| Managed identity (system or user-assigned) | App Service, Container Apps, AKS, Functions, Container Instances pulling images | Recommended. Zero secrets in your app. Assign the identity AcrPull role on the registry |
| ACR token with scope map | Limited automation that needs read-only pull from one repo | Tokens are scoped per repository, can be disabled |
| Admin user | Quick demos only | Disabled by default in production. Single shared credential β breaks audit trails |
The exam strongly favours managed identity. If a question shows a long-lived password or shared admin user as one of four options, thatβs almost certainly the wrong answer.
# Grant a Container App's managed identity AcrPull on the registry:
az role assignment create \
--assignee $PRINCIPAL_ID \
--role AcrPull \
--scope $(az acr show -n roo --query id -o tsv)
Repositories, untagged manifests, and cleanup
A repository can grow forever β every push creates a new manifest. Untagged manifests (orphaned by tag overwrites) accumulate quickly.
# Show repositories
az acr repository list --name roo
# Show all tags + digests in a repo
az acr repository show-manifests --name roo --repository roo-vision
# Remove untagged manifests older than 7 days
az acr run --registry roo --cmd \
"acr purge --filter 'roo-vision:.*' --untagged --ago 7d" /dev/null
Set up a retention policy on Premium registries to auto-delete untagged manifests older than N days. Storage cost compounds fast on large model images (several GB each).
Content trust and image signing
For workloads that must prove image provenance, Premium ACR supports image signing with Notation v2 (the modern successor to Docker Content Trust). Signed images carry a verifiable signature that downstream consumers (AKS gatekeeper, container apps, Defender for Containers) can validate.
| Step | Tool | Notes |
|---|---|---|
| Generate a signing certificate | Azure Key Vault | The signing key never leaves Key Vault |
| Sign on push | notation sign $(az acr login -n roo --expose-token) | Signing is a separate manifest in the registry |
| Verify on pull | Notation policy + Defender for Containers | Reject unsigned or tampered images |
Key terms
Knowledge check
Mira at Roo Robotics needs to host the same vision-inference image close to warehouses in West Europe and Australia East to minimise pull latency during deployment. Which ACR SKU does she need?
Theo at Tidewater Health is finalising the AKS deployment and wants to remove the password the cluster currently uses to pull from ACR. What is the recommended approach?
Lin's pipeline pushes a new build and tags it `:v1.2`, overwriting the previous tag. Several App Service instances continue to run the old code for hours afterwards. What is happening, and what should Lin do?