Publishing Images to Azure Container Registry
Complete the full lesson to earn 25 points
Work through each section, then tap “Mark as Complete” on the last one.
Publishing Images to Azure Container Registry (ACR)
Introduction: The Foundation of Modern Deployment
In the current landscape of software development, the shift toward containerization has fundamentally changed how we package and distribute applications. By bundling an application with its entire runtime environment—including libraries, dependencies, and configuration files—containers ensure that software runs exactly the same way regardless of the underlying infrastructure. However, simply creating a container image on a local machine is only half the battle. To deploy these applications to production environments like Azure Kubernetes Service (AKS), Azure Container Apps, or Azure App Service, you need a central, secure, and accessible location to store those images.
This is where the Azure Container Registry (ACR) enters the picture. ACR is a managed, private Docker registry service based on the open-source Docker Registry 2.0. Think of it as a private, cloud-hosted library for your container images. When you "publish" an image to ACR, you are essentially pushing your compiled application artifact to a secure repository where your cloud infrastructure can pull it down and run it. Understanding how to manage, push, and secure these images is a foundational skill for any cloud developer working within the Microsoft ecosystem.
Mastering ACR is critical because it bridges the gap between your local development workstation and the cloud. Without a robust registry strategy, you risk security vulnerabilities, slow deployment cycles, and inconsistent application versions across your environments. In this lesson, we will explore the lifecycle of an image, the mechanics of authentication, the nuances of tagging, and the best practices for maintaining a clean and secure registry.
Understanding the Architecture of ACR
Before we dive into the commands and configurations, it is important to understand what ACR actually does. At its core, ACR is a storage service that organizes images into repositories. A repository is a collection of images that share the same name but have different tags, such as my-app:v1, my-app:v2, or my-app:latest.
When you publish an image to ACR, you are performing a docker push operation. However, behind the scenes, Azure handles the networking, encryption at rest, and access control. Because ACR is integrated directly into Azure’s Identity and Access Management (IAM) system, you can control exactly who—or which machine—is allowed to push or pull images. This integration is one of the primary reasons organizations choose ACR over public registries like Docker Hub for internal enterprise applications.
The Role of Repositories and Tags
In a typical development workflow, you will have multiple versions of an application. You might have a frontend service and a backend service. Each of these would exist as a separate repository within your ACR instance. Within those repositories, tags act as the version control mechanism. While developers often use latest for quick testing, using specific semantic versioning (like 1.0.4) is a best practice for production workloads to ensure you always know exactly which code is running in your cluster.
Callout: Registry vs. Repository It is common for newcomers to confuse the two terms. A Registry is the entire service instance (e.g.,
mycompany.azurecr.io). It acts as the host. A Repository is a collection of related images grouped under a specific name (e.g.,mycompany.azurecr.io/web-app). You can think of the Registry as the library building, and the Repositories as the individual bookshelves inside that building.
Setting Up Your Environment
To publish images to ACR, you need to have a few tools installed on your local machine. These tools are standard across the industry and will serve you well in almost any container-related task.
- Docker Desktop or Docker Engine: You need the Docker daemon running to build and tag your images locally.
- Azure CLI (az): This is the primary tool for interacting with Azure resources from your terminal.
- An Active Azure Subscription: You need a place to host your registry.
Creating the Registry
If you do not already have a registry, you can create one using the Azure CLI. Run the following command in your terminal:
# Create a resource group
az group create --name my-container-rg --location eastus
# Create the registry
az acr create --resource-group my-container-rg \
--name myuniqueacrname \
--sku Basic
The --sku parameter determines the features, storage limits, and cost of your registry. The 'Basic' tier is perfect for learning and small projects, while 'Standard' and 'Premium' tiers offer features like geo-replication, private link support, and higher throughput.
The Publishing Workflow: Step-by-Step
Publishing an image is a three-stage process: Authentication, Tagging, and Pushing. Let’s walk through each stage in detail.
1. Authentication
Before you can interact with your registry, you must prove to Azure that you have the right to push images. The easiest way to do this is using the Azure CLI.
# Log in to Azure
az login
# Authenticate your Docker client with the specific registry
az acr login --name myuniqueacrname
When you run az acr login, the Azure CLI updates your local Docker configuration file (usually found at ~/.docker/config.json) with the necessary credentials. This allows the standard docker command to communicate directly with your private Azure registry.
Note: If you are working in a CI/CD pipeline (like GitHub Actions or Azure DevOps), you should avoid
az loginand instead use Service Principals or Managed Identities to authenticate. These are more secure because they do not require interactive user sessions.
2. Tagging the Image
Docker images are identified by their names. To push an image to your private registry, you must rename your local image to match the registry's URL. The format follows this pattern: [registry-name].azurecr.io/[repository-name]:[tag].
Suppose you have a local image named my-web-app with the tag v1. To prepare it for ACR:
# Tag the local image
docker tag my-web-app:v1 myuniqueacrname.azurecr.io/my-web-app:v1
This does not create a copy of the image; it simply adds a pointer to the existing local image so that Docker knows where it needs to go when you execute the push command.
3. Pushing the Image
Now that the image is correctly named, you can upload it to your registry.
# Push the image to ACR
docker push myuniqueacrname.azurecr.io/my-web-app:v1
Once the command completes, you can verify the upload by listing the images in your registry via the Azure CLI:
# List repositories
az acr repository list --name myuniqueacrname --output table
# List tags for a specific repository
az acr repository show-tags --name myuniqueacrname --repository my-web-app --output table
Advanced Management and Best Practices
As your projects grow, simply pushing images is not enough. You need to manage the lifecycle of these images to keep costs down and security high.
Image Lifecycle Management
Registry storage costs money. If you push a new image every time you make a code change, your registry will quickly become bloated with hundreds of unused tags. Azure provides "Retention Policies" that automatically delete old or untagged images.
You can configure a retention policy using the Azure CLI:
az acr config retention update --registry myuniqueacrname \
--days 7 \
--type UntaggedManifests \
--status Enabled
This command tells ACR to automatically delete any image manifests that are no longer associated with a tag after 7 days, which is a great way to keep your storage clean.
Security: Scanning for Vulnerabilities
One of the most powerful features of ACR is its integrated vulnerability scanning, powered by Microsoft Defender for Cloud. When you push an image, ACR can automatically scan the layers for known vulnerabilities (CVEs).
Callout: Why Scan Images? Container images are often built from base images (like Alpine or Debian) that may contain outdated packages. If you don't scan your images, you might unknowingly deploy a container with a critical security flaw. Enabling automated scanning gives you a report of exactly which software packages in your image are vulnerable and provides guidance on how to fix them.
To view the results of a scan, navigate to your registry in the Azure Portal, select "Repositories," click on the image repository, and view the "Vulnerability report" tab.
Using Build Tasks (ACR Build)
While building locally is fine for testing, it is often better to let Azure build your images for you. This ensures that the build happens in a clean, consistent environment. You can use the az acr build command to send your source code to Azure, where it will be built into an image and pushed directly to your registry.
# Build and push directly from a local folder
az acr build --registry myuniqueacrname --image my-web-app:v1 .
This method is highly recommended for production pipelines because it removes the dependency on the developer's local machine environment. It also allows you to automate the build process using triggers, such as pushing code to a GitHub repository.
Common Pitfalls and Troubleshooting
Even experienced engineers run into issues when working with container registries. Here are some of the most common mistakes and how to fix them.
1. Authentication Failures
If you receive an "access denied" error when pushing, it is almost always an authentication issue.
- Check your login: Have you run
az acr loginrecently? The token might have expired. - Check your permissions: Ensure your Azure account has the "AcrPush" role assigned to it within the registry's Access Control (IAM) settings.
2. "Repository Not Found" Errors
This often happens if you mistype the registry URL. Remember, the registry URL must be exactly [registry-name].azurecr.io. If you are using a custom domain or a private endpoint, the URL might differ, so always verify the login server address in the Azure portal.
3. Pushing Large Images
If you find that your pushes are timing out or are extremely slow, you might be including unnecessary files in your image.
- Use .dockerignore: Just like
.gitignore, a.dockerignorefile prevents local files (likenode_modules,.gitfolders, or local logs) from being copied into your image during the build process. A smaller image is faster to build, faster to push, and faster to pull when your cluster starts the container.
4. Overwriting Tags
Never overwrite the latest tag in a production environment. If you push my-app:latest and it turns out to be broken, you have no easy way to roll back to the previous version. Always use unique, immutable tags (like version numbers or Git commit hashes) for production images.
Comparison: Registry Tiers
Choosing the right SKU for your ACR instance is a balance between performance and cost.
| Feature | Basic | Standard | Premium |
|---|---|---|---|
| Storage | 10 GB | 100 GB | 500 GB |
| Throughput | Lower | Higher | Highest |
| Geo-replication | No | No | Yes |
| Private Link | No | No | Yes |
| Content Trust | Yes | Yes | Yes |
- Basic: Best for individual developers, learning, and small personal projects.
- Standard: Suitable for small teams and production environments that do not require complex networking or multi-region support.
- Premium: Required for enterprise-grade applications, multi-region deployments (where you need low-latency access from different parts of the world), and strict security requirements involving private virtual networks.
Best Practices for Enterprise Registries
When moving from a local project to an enterprise environment, your approach to ACR must change. Consistency and security become the primary drivers for your configuration.
Use Immutable Tags
In production, tags should be immutable. Once a tag (e.g., v1.2.0) is pushed, it should never be changed or overwritten. If you need to make a change, increment the version to v1.2.1. This provides an audit trail and prevents the "it worked yesterday but not today" problem caused by an overwritten image. You can enforce this in ACR by enabling the "Tag Immutability" setting.
Implement Content Trust
Content Trust allows you to sign your images using a private key. When you push an image to ACR, you sign it. When your Kubernetes cluster pulls the image, it verifies the signature. This ensures that the image has not been tampered with between the build process and the deployment.
Leverage Geo-Replication
If your application is used by customers in both North America and Europe, you don't want your servers in Europe to pull images from a registry in the US. With the Premium SKU, you can enable geo-replication. This automatically mirrors your registry across multiple Azure regions, ensuring that your images are always pulled from a local, high-speed source.
Automate with CI/CD
Never manually run docker push for production releases. Use a CI/CD tool (like GitHub Actions, GitLab CI, or Azure Pipelines) to handle the build and push process. This ensures that every image in your registry is tied to a specific Git commit and a clean build log.
Tip: Use the "ACR Tasks" feature to automate image patching. If a base image (e.g., a specific version of Node.js) receives a security update, ACR Tasks can automatically rebuild your application images that depend on that base image.
FAQ: Common Questions
Q: Can I share my registry with other people? A: Yes. You can use Azure IAM to grant "AcrPull" or "AcrPush" roles to other users or service principals in your Azure tenant. This is the secure way to share access, rather than sharing a username and password.
Q: What happens if I delete an image? A: Once an image is deleted from the registry, it is gone. If your running containers depend on that image and they attempt to restart or scale out, they will fail to pull the image. Always ensure your deployment manifest references a tag that exists in the registry.
Q: Does ACR support non-Docker images? A: Yes. ACR follows the OCI (Open Container Initiative) distribution specification. This means it can store Helm charts, OPA (Open Policy Agent) bundles, and other artifacts that follow the OCI standard.
Q: How do I move images between registries?
A: You can use the az acr import command. This is much faster than pulling the image to your local machine and pushing it again, as it performs the transfer entirely within the Azure backbone network.
Key Takeaways
As we conclude this lesson, keep these fundamental principles in mind. They represent the industry standards for managing containerized solutions in Azure.
- Registry as a Source of Truth: Treat your ACR as the single source of truth for your production-ready container images. If an image isn't in ACR, it shouldn't be running in your cluster.
- Authentication Matters: Always prefer Managed Identities or Service Principals over interactive user logins for automated systems. Secure your registry using Azure RBAC.
- Tagging Hygiene: Adopt a clear tagging strategy. Use semantic versioning (e.g.,
1.2.3) instead of generic tags likelatestto ensure reproducibility and easy rollbacks. - Security by Design: Enable vulnerability scanning immediately. Use
.dockerignoreto reduce image size and attack surface, and consider enabling tag immutability for production repositories. - Automate Everything: Use ACR Tasks or CI/CD pipelines to build and push images. Manual intervention is the leading cause of "configuration drift" and human error in deployment pipelines.
- Cost and Lifecycle Management: Implement retention policies to clean up your registry. You don't need to pay for storage of images that were used for a single build three months ago.
- Choose the Right SKU: Start small with the Basic tier, but be prepared to upgrade to Premium for features like Private Link, geo-replication, and advanced security if your organization requires it.
By following these practices, you ensure that your containerized solutions are not just functional, but also secure, scalable, and easy to maintain. ACR is a powerful component of the Azure ecosystem, and mastering it is a significant step toward becoming a proficient cloud developer.
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- ✓ Fewer advertisements
- ✓ 2× daily points limit
- ✓ Distraction-free lessons