Build a Private Container Registry in Azure: ACR Basics for Beginners and Admins
Here’s the rewritten guide with improved flow, tighter prose, and clearer structure:
Building a Private Container Registry in Azure (ACR)
A hands-on guide to creating, populating, and using Azure Container Registry with the portal, Azure CLI, and Docker.
When you run containers in Azureโwhether in Container Apps, Container Instances, or AKSโyou need a container image. That image must live in a registry. You have two choices:
| Type | Examples | Use Case |
|---|---|---|
| Public | Docker Hub, Microsoft Container Registry | Open-source apps, samples |
| Private | Azure Container Registry (ACR) | Enterprise apps, internal code, compliance |
This guide walks you through creating a private ACR, pushing your first image, and preparing for production deployment.
1) Why You Need a Registry
A container image packages your application with its dependencies. A registry stores and distributes those images.
Without a registry:
- Build manually on every host (slow, inconsistent)
- Copy images via USB or SCP (messy, insecure)
With a registry:
- Build once, deploy anywhere
- Version releases with tags (
v1.2.0,prod,latest) - Control access via Azure RBAC
- Automate CI/CD pipelines
2) Create an Azure Container Registry
Portal Method
- Azure portal โ Create a resource โ Search “Container Registry”
- Basics tab:
- Registry name: Globally unique (e.g.,
mycompanyacr) - Region: Match your workload location for lower latency
- SKU: Choose based on needs:
| SKU | Best For | Key Features |
|---|---|---|
| Basic | Dev/test, learning | Lowest cost, 10GB storage |
| Standard | Small-to-mid production | 100GB storage, geo-replication |
| Premium | Enterprise | Private endpoints, CMK encryption, enhanced throughput |
- Networking (Premium only): Disable public access, enable Private Endpoint
- Encryption: Microsoft-managed keys (default); Premium supports customer-managed keys (CMK)
- Click Review + create โ Create
Deployment time: ~30-60 seconds
3) Get Your Login Server
After deployment, open your ACR resource. Copy the Login server:
mycompanyacr.azurecr.io
You’ll use this for all Docker commands.
4) Authenticate with ACR
# Login to Azure (if not already)
az login
# Authenticate Docker to ACR
az acr login --name mycompanyacr
Note: Use the registry name (
mycompanyacr), not the full domain.
Verify connectivity:
az acr repository list --name mycompanyacr -o table
# Expected: Empty list (or your existing repos)
5) Prepare Your Environment
Prerequisites:
- Docker Desktop (Windows/Mac) or Docker Engine (Linux)
- Azure CLI installed
Verify Docker:
docker version
docker info
6) Pull a Sample Image
docker pull mcr.microsoft.com/appsvc/staticsite:latest
Verify local images:
docker images | grep staticsite
7) Test Locally (Optional but Recommended)
Validate the image works before pushing:
docker run --name test-site -p 8080:80 mcr.microsoft.com/appsvc/staticsite:latest
Browse to http://localhost:8080. You should see the static site.
Clean up:
docker stop test-site && docker rm test-site
8) Tag for ACR
Docker push requires the full registry path:
docker tag mcr.microsoft.com/appsvc/staticsite:latest mycompanyacr.azurecr.io/staticsite:v1.0.0
Verify the new tag:
docker images | grep mycompanyacr
9) Push to ACR
docker push mycompanyacr.azurecr.io/staticsite:v1.0.0
You’ll see layer upload progress. When complete, the image lives in your private registry.
10) Verify the Push
CLI method:
# List repositories
az acr repository list --name mycompanyacr -o table
# List tags
az acr repository show-tags --name mycompanyacr --repository staticsite -o table
Portal method:
- ACR resource โ Repositories โ
staticsiteโ viewv1.0.0tag
11) Deploy Your Image
Now use your image across Azure container services:
| Service | Integration Method | Best For |
|---|---|---|
| Container Instances (ACI) | Managed identity or admin credentials | One-off tasks, simple apps |
| Container Apps | System-assigned identity + AcrPull role | Autoscaling, microservices, serverless |
| AKS | Cluster identity + AcrPull | Full Kubernetes orchestration |
Example: Grant Container Apps access
# Assign AcrPull role to Container Apps managed identity
az role assignment create \
--assignee <container-app-identity-id> \
--role AcrPull \
--scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.ContainerRegistry/registries/mycompanyacr
12) Production Best Practices
| Practice | Implementation |
|---|---|
| Semantic versioning | Use v1.0.0 instead of latest for reproducible deployments |
| Managed identity | Disable admin user; use Azure AD authentication |
| Private networking | Premium SKU + Private Endpoint for “no public IP” requirements |
| Image scanning | Enable Microsoft Defender for Cloud or Azure Policy |
| Retention policies | Auto-purge untagged manifests and old images |
| Geo-replication | Enable for multi-region deployments (Standard+) |
13) Troubleshooting Quick Fixes
| Symptom | Cause | Fix |
|---|---|---|
unauthorized: authentication required | Token expired | az acr login --name mycompanyacr |
repository name not known | Typo in image name | Run docker images to verify exact name |
denied: requested access to the resource is denied | RBAC missing | Grant AcrPush (for writes) or AcrPull (for reads) |
| Runtime can’t pull image | Identity lacks permissions | Assign AcrPull to the service’s managed identity |
| Push succeeds but pull fails from AKS | Network/firewall rules | Check NSG rules or Private Endpoint DNS configuration |
Quick Reference: Full Workflow
# 1. Create registry (Portal or CLI)
az acr create --resource-group myRG --name mycompanyacr --sku Standard
# 2. Login
az acr login --name mycompanyacr
# 3. Pull, tag, push
docker pull mcr.microsoft.com/appsvc/staticsite:latest
docker tag mcr.microsoft.com/appsvc/staticsite:latest mycompanyacr.azurecr.io/staticsite:v1.0.0
docker push mycompanyacr.azurecr.io/staticsite:v1.0.0
# 4. Verify
az acr repository list --name mycompanyacr -o table
