Background
Sections
IntroductionFoundations1. Resource Hierarchy2. Resource Manager3. Identity and RBAC4. Regions and Availability5. Naming and TaggingVirtual Machines1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetVirtual Network1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetBlob Storage1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure SQL Database1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Kubernetes Service1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Container Registry1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetMicrosoft Entra ID1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure RBAC1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Functions1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAPI Management1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure App Configuration1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Machine Learning1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Monitor1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure AI Foundry1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and Cheatsheet

Azure Container Registry

13 min read

ACR is a private, managed OCI registry — the place your build pipeline pushes images to and your runtime pulls them from, addressed as myregistry.azurecr.io. It is Docker Hub with your name on it, an Entra ID login instead of a username, a firewall in front of it, and a bill attached to the storage.

Names: the service has always been Azure Container Registry (ACR). Two names you'll meet in older material and should treat as dead: the original Classic SKU (retired — Basic, Standard, and Premium are the whole SKU list now) and content trust / Docker Content Trust, ACR's Notary v1 image-signing feature, which is on a retirement path in favour of Notation (Notary v2) with keys in Key Vault ⚠️ verify the current retirement date against Azure docs. One name is easy to misread: Cache for ACR (pull-through caching, once marketed as "artifact cache") is a feature of ACR, not a separate service.

What it is and where it fits

A container registry is a content-addressed store with a very small API: you PUSH a manifest and its layers under a repository name and tag, and you PULL them back by name or by digest. The protocol is the OCI Distribution Specification (still widely called the Docker Registry HTTP API V2), which means every client on earth — docker, podman, containerd, helm, oras, kubelet — already speaks it. ACR's job is to run that endpoint for you, durably, with Azure's identity model bolted onto the front and Azure's networking model bolted onto the side.

The problem it kills is not "storing tarballs." It's storing tarballs that a Kubernetes cluster will pull ten thousand times an hour, from a network you control, under an identity you can audit, without a password in a YAML file. Before a managed registry, teams ran the open-source registry:2 container on a VM behind a load balancer, backed it with a storage account, bolted on their own TLS and auth, and then discovered that nobody owned garbage collection. ACR makes that a resource type.

Where it sits in the catalogue is unusual: ACR is the only service in Azure's compute category that almost nothing uses directly and almost everything depends on. AKS pulls from it. Container Apps pulls from it. App Service for Containers pulls from it. Azure Functions in a custom container pulls from it. Azure ML environments are built into it. Every topic in this article that runs a container eventually points here.

The neighbours worth separating, one line each:

  • Docker Hub — the public default. Free, rate-limited for anonymous and free-tier pulls, and outside your network boundary. The single most common reason to adopt ACR is that a Docker Hub rate limit took production down at the worst possible moment.
  • Microsoft Artifact Registry (mcr.microsoft.com) — Microsoft's public registry for its own base images. You pull from it; you cannot push to it. ACR's cache feature exists partly to put a local copy of MCR images inside your boundary.
  • GitHub Packages / GitHub Container Registry (ghcr.io) — a genuine alternative if your whole supply chain already lives in GitHub. It loses Azure-native private endpoints, Entra RBAC on the registry resource, and geo-replication.
  • Azure Artifacts (in Azure DevOps) — for NuGet, npm, Maven, and Python packages, not container images. Different problem, adjacent shelf.
  • Blob Storage — not an alternative. ACR uses Microsoft-managed storage internally; you never see the storage account, and you cannot point ACR at your own.

If you're coming from AWS: ACR is ECR, and most of the model transfers — private registry, IAM-backed auth, per-GB storage plus egress, immutable tags, lifecycle/retention policies, image scanning through the security product rather than the registry itself. Where it breaks: ECR gives you one registry per account per region and repositories are the resource you attach IAM policies to; ACR gives you a named registry resource and repositories are just strings inside it, with no per-repository ARM resource and therefore no per-repository Azure RBAC — you get per-repository access only through Premium's scope maps and tokens, which have no ECR equivalent. ACR also has no resource-based policy: there is no ACR analogue of an ECR repository policy, so cross-tenant sharing is done with tokens or with a role assignment, not a JSON policy document. And ACR's geo-replication is one registry with many regional replicas behind a single login server, where ECR asks you to configure replication between distinct regional registries.

[Image Prompt: 2D minimalistic diagram of Azure Container Registry sitting between build systems on the left — CI pipelines and ACR Tasks — and runtimes on the right — AKS, Container Apps, App Service, and Azure Functions — with a single azurecr.io login server in the middle, flat design, clean vector art style, white background]

Key facts at a glance

Category Compute — container image and OCI artifact registry
Resource provider Microsoft.ContainerRegistry/registries (child types: .../replications, .../tasks, .../scopeMaps, .../tokens, .../webhooks, .../cacheRules, .../credentialSets)
Scope Regional resource with a globally unique namemyregistry.azurecr.io is a DNS name in a shared namespace, so the name is taken tenant-wide across all of Azure. Premium adds regional replicas behind that one name, and zone redundancy per region
The SKU axis — tier Basic / Standard / Premium. The tiers differ in included storage, throughput, and — the part that actually decides it — which features exist at all. Premium is the only tier with private endpoints, geo-replication, customer-managed keys, scope-map tokens, zone redundancy, connected registry, and dedicated data endpoints
The trap tier Basic. It is cheap, and it is fine for a demo, but it has no private endpoint support — so the day someone adds "no public network access" to the security baseline, you are migrating tiers under pressure. Tier changes are online and non-destructive, which softens this, but the network design you built around a public endpoint isn't
Unit of billing A fixed per-day price per tier (which buys an included storage allowance), plus per-GiB/day for storage above it, plus egress out of the region, plus per-region for each geo-replica (each replica bills roughly a second registry at the Premium daily rate), plus ACR Tasks compute per CPU-second beyond a free monthly allowance ⚠️ verify all figures against current Azure pricing
The billing trap The daily tier price is charged whether or not anyone pulls a single image — a forgotten Premium registry with a replica in three regions is a real monthly line item doing nothing. Second trap: untagged manifests from repeated CI pushes accumulate forever unless you set a retention policy
Included storage (approx.) Basic ~10 GiB, Standard ~100 GiB, Premium ~500 GiB, overage per GiB/day ⚠️ verify against current Azure docs — these are the numbers most likely to have moved
Control plane / data plane ARM governs the registry resource; the azurecr.io endpoint governs images, and they have separate roles. Reader on the registry does not let you pull. AcrPull / AcrPush do, and grant no ARM rights
SLA posture An availability SLA on the registry endpoint, quoted per tier ⚠️ verify current percentages. Geo-replication and zone redundancy change your effective availability, not the printed number
Usual companions AKS, Container Apps, App Service, Azure Functions, Key Vault, Microsoft Defender for Cloud (vulnerability scanning), GitHub Actions / Azure Pipelines, Microsoft Entra ID + managed identities, Private Link + Private DNS
Primary alternative GitHub Container Registry if your supply chain is GitHub-native; Docker Hub only for public images you don't mind depending on
AWS rough analogue Amazon ECR (private) — see the caveats above; ECR Public ≈ nothing in ACR, which has no public-registry product

When to use ACR

  • Anything that runs a container in Azure. This is the default, and it is the default for a boring reason: the pull path stays on Azure's network, the credentials are a managed identity, and the failure mode isn't "Docker Hub throttled us."
  • You need the pull to be private. Premium + private endpoint + Private DNS means nodes resolve myregistry.azurecr.io to a VNet-internal address and never touch the public internet.
  • You're pulling the same images from several regions. Geo-replication gives you one image name, one push, and a local pull everywhere — a genuinely good feature with no ECR equivalent in shape.
  • You want to store more than images. Helm charts, SBOMs, signatures, WASM modules, and arbitrary ORAS artifacts all live here, because they're all OCI artifacts.
  • You want builds close to the registry. ACR Tasks builds images in Azure without a build agent, and — its real party trick — can automatically rebuild your image when its base image changes, which is the cheapest CVE-remediation loop available.
  • You're behind a Docker Hub rate limit or an air gap. Cache rules turn ACR into a pull-through cache for upstream registries, and the connected registry feature (Premium) puts a synchronised replica on-premises or at the edge.

When not to use ACR

  • You need a public registry for a public project. ACR has anonymous-pull (Standard and Premium) and it works, but you are paying per-GiB and per-egress-GB to distribute someone else's copy. Docker Hub, ghcr.io, or MCR are the right shelf for genuinely public distribution.
  • You want per-repository IAM the way ECR does it. Azure RBAC's finest grain on a registry is the whole registry. Repository-level access requires Premium scope maps and tokens, which issue a password, not an Entra identity — a real step down in auditability. If you need strict per-team isolation, the honest Azure answer is often one registry per boundary, not one registry with clever tokens.
  • As a general artifact store. ORAS will happily push a 4 GB tarball, and ACR will happily charge you for it. Use Blob Storage for blobs and Azure Artifacts for packages.
  • As your only copy of anything. Geo-replication protects against a region; it does not protect against az acr repository delete. Soft delete is a policy you have to switch on ⚠️ verify current preview/GA status, and it is not a backup product.
  • Basic tier for anything with a network requirement. Covered above, and worth repeating: this is the most common ACR regret.

What this topic covers

Sub-topic What it covers
What & Why The problem a private registry solves, where ACR sits among Docker Hub / MCR / GHCR, the ECR analogue and where it breaks, and the honest anti-patterns
Core Concepts Registry, repository, tag, manifest, digest, layer, OCI artifact, the SKU axis, tokens and scope maps, replications, tasks, and the vocabulary traps
Architecture What actually happens during a docker push and a kubelet pull, the Entra token exchange, control plane vs. data plane, storage and dedup, geo-replication, and the failure modes
Getting Started One registry, three ways — portal, az CLI, minimal Terraform — build an image, push it, pull it, then delete the resource group
Deployment A parameterised Terraform module, remote state, an Ansible playbook for day-2 work, the Bicep equivalent, OIDC CI/CD, environment promotion by digest, rollback, and drift
Integrations AKS, Container Apps, App Service, Functions, Key Vault, Defender for Cloud, Event Grid, and the managed-identity and private-endpoint glue
Production Security, cost, scaling and throughput limits, observability, and reliability — plus the tag-immutability and retention discipline that keeps a registry sane
Interview Questions Three tiers with answer keys, from "what is a manifest" to "the same tag is running two different builds in two regions"
Glossary & Cheatsheet Every term in one line, the az acr commands you'll actually type, the resource ID shape, and the limits worth knowing

Three ideas worth carrying into every other page

A tag is a pointer, and a digest is the thing. myapp:v1.2 is a mutable label; myapp@sha256:9f86d0… is content-addressed and cannot mean anything else, ever. Every hard problem in registry operations — "it works in staging but not prod", "the rollback didn't roll back", "the scan passed but the running image is vulnerable" — is a tag being treated as a digest. Promote by digest between environments and turn on tag immutability, and most of the class disappears.

Reader does not mean read. The single most common ACR support question is a pipeline that can see the registry in the portal and cannot pull from it. Control-plane RBAC (Owner, Contributor, Reader) governs the ARM resource; data-plane RBAC (AcrPull, AcrPush, AcrDelete) governs the images. They're both Azure RBAC, assigned at the same scope, which is exactly why people assume one implies the other. It doesn't — with one nasty exception: Contributor can call az acr credential show and hand itself the admin user's password, which is full data-plane access through a side door. That is the argument for keeping the admin user disabled.

The registry is a dependency of your recovery, so treat it like one. If your disaster plan is "redeploy the cluster in the paired region," and your images live in a single-region Basic registry in the region that just failed, you have a plan that cannot execute. Geo-replication is not a nice-to-have for multi-region architectures; it's the thing that makes the rest of the plan real.

Reading paths

New to container registriesWhat & WhyCore ConceptsGetting Started. Push one image, pull it back by digest, then read Architecture.

Coming from ECR — skim What & Why, then go straight to Core Concepts for the registry-is-the-resource model and scope maps, and to Architecture for the Entra token exchange, which has no ECR analogue.

Wiring ACR to AKS or Container AppsIntegrations first, then the security section of Production. The whole answer is usually "managed identity plus an AcrPull role assignment," and the whole difficulty is usually DNS.

Need to ship this quarterDeployment, then Production. Getting Started is deliberately throwaway.

Chasing a cost surprise — the cost section of Production. Untagged manifests from CI, an unused geo-replica, and cross-region egress from a cluster pulling from another region's registry are, in that order, the three usual culprits.

Interview or certification prepCore Concepts, Architecture, and Interview Questions. The "how does AKS authenticate to ACR without a secret" question is close to guaranteed.


Next: What & Why →

← Back to the article