{"id":406,"date":"2026-04-13T22:58:42","date_gmt":"2026-04-13T22:58:42","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/azure-container-registry-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-containers\/"},"modified":"2026-04-13T22:58:42","modified_gmt":"2026-04-13T22:58:42","slug":"azure-container-registry-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-containers","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/azure-container-registry-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-containers\/","title":{"rendered":"Azure Container Registry Tutorial: Architecture, Pricing, Use Cases, and Hands-On Guide for Containers"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Category<\/h2>\n\n\n\n<p>Containers<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Introduction<\/h2>\n\n\n\n<p>Azure Container Registry is Azure\u2019s managed, private registry service for storing and distributing container images and related Open Container Initiative (OCI) artifacts. If your team builds containers, you need a reliable place to push images, control who can pull them, and integrate that registry into CI\/CD and runtime platforms like Azure Kubernetes Service (AKS), Azure Container Apps, and Azure Container Instances (ACI).<\/p>\n\n\n\n<p>In simple terms: <strong>Azure Container Registry is \u201cprivate Docker Hub for your organization\u201d hosted in Azure<\/strong>, with Azure Active Directory (Microsoft Entra ID) authentication, Azure networking controls, and integrations with Azure\u2019s container and DevOps ecosystem.<\/p>\n\n\n\n<p>Technically, Azure Container Registry (often abbreviated <strong>ACR<\/strong>) is a <strong>regional Azure resource<\/strong> that implements the <strong>Docker Registry HTTP API v2 \/ OCI distribution<\/strong> patterns. It supports authenticated push\/pull, webhook events, build automation (ACR Tasks), replication options, and enterprise security controls (for example, private connectivity and granular authorization depending on SKU and configuration). You typically place ACR close to your compute to reduce latency and egress costs, and you secure it with Entra ID + Azure RBAC, network restrictions, and auditing.<\/p>\n\n\n\n<p><strong>What problem it solves:<\/strong> It provides a secure, scalable, Azure-native way to store and deliver container artifacts\u2014eliminating reliance on public registries for production workloads, enabling repeatable deployments, and improving governance over what runs in your clusters and container platforms.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. What is Azure Container Registry?<\/h2>\n\n\n\n<p><strong>Official purpose:<\/strong> Azure Container Registry is a managed service for <strong>storing and managing container images and OCI artifacts<\/strong> in Azure, with enterprise authentication\/authorization and integrations for building and deploying containers. Official documentation: https:\/\/learn.microsoft.com\/azure\/container-registry\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Core capabilities<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Private registry for container images<\/strong> (push\/pull, tag management, repository organization).<\/li>\n<li><strong>OCI artifact support<\/strong> (container images and other OCI-compliant artifacts). Exact supported artifact types and tooling can evolve\u2014verify in official docs for your scenario.<\/li>\n<li><strong>Authentication and authorization<\/strong> using Microsoft Entra ID (Azure AD) and Azure RBAC; optional registry credentials (admin user) for labs or legacy scenarios.<\/li>\n<li><strong>Automation features<\/strong> such as <strong>ACR Tasks<\/strong> for cloud builds and triggers (for example, build on commit, build on base image update, schedule builds).<\/li>\n<li><strong>Integrations<\/strong> with Azure container runtimes (AKS, Container Apps, ACI) and CI\/CD systems (GitHub Actions, Azure DevOps, other pipelines).<\/li>\n<li><strong>Networking controls<\/strong> such as private connectivity options and firewall rules (availability can be SKU-dependent\u2014verify in official docs).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Major components (conceptual)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Registry<\/strong>: The top-level ACR resource (e.g., <code>mycompanyacr.azurecr.io<\/code>) that hosts repositories.<\/li>\n<li><strong>Repositories<\/strong>: Logical groupings of artifacts (e.g., <code>payments\/api<\/code>, <code>platform\/nginx<\/code>).<\/li>\n<li><strong>Tags<\/strong>: Human-friendly pointers to immutable manifests (e.g., <code>1.4.2<\/code>, <code>prod<\/code>, <code>sha-...<\/code>).<\/li>\n<li><strong>Manifests<\/strong>: Immutable references to image layers and metadata (OCI\/Docker manifest).<\/li>\n<li><strong>Layers<\/strong>: The content blobs that make up images.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Service type<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Managed PaaS<\/strong> registry service (you don\u2019t manage VMs or storage accounts directly).<\/li>\n<li>API-driven and compatible with standard container tooling (Docker, Podman, Kubernetes, Helm OCI workflows, and other OCI tools\u2014verify tool compatibility for your versions).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Scope and locality<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Resource scope:<\/strong> ACR is created in an <strong>Azure subscription<\/strong> and <strong>resource group<\/strong>.<\/li>\n<li><strong>Region:<\/strong> ACR is a <strong>regional<\/strong> Azure resource (you choose a region at creation). Some advanced capabilities (replication, zone redundancy, private features) may vary by region and SKU\u2014verify in official docs.<\/li>\n<li><strong>Endpoint:<\/strong> A registry exposes a login server such as <code>myregistry.azurecr.io<\/code>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How it fits into the Azure ecosystem<\/h3>\n\n\n\n<p>Azure Container Registry is commonly used as the artifact hub between:\n&#8211; <strong>Build systems<\/strong> (GitHub Actions, Azure DevOps, ACR Tasks) that produce images\n&#8211; <strong>Security tooling<\/strong> (Microsoft Defender for Cloud plans, policy enforcement, signing strategies\u2014verify current recommendations)\n&#8211; <strong>Deployment targets<\/strong> (AKS, Azure Container Apps, ACI, App Service for Containers)\n&#8211; <strong>Identity and governance<\/strong> (Microsoft Entra ID, Azure RBAC, Azure Policy, Azure Monitor)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Why use Azure Container Registry?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Business reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Control and governance:<\/strong> Keep production artifacts in a registry you own and govern, rather than relying on public registries.<\/li>\n<li><strong>Reduced supply-chain risk:<\/strong> Support private distribution, controlled access, and security integrations.<\/li>\n<li><strong>Operational consistency:<\/strong> Standardize how teams publish and consume images across environments (dev\/test\/prod).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technical reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>OCI\/Docker compatibility:<\/strong> Works with standard container tools and Kubernetes pull mechanisms.<\/li>\n<li><strong>Azure-native authentication:<\/strong> Integrates with Entra ID and Azure RBAC rather than separate registry accounts.<\/li>\n<li><strong>Regional placement:<\/strong> Put the registry close to compute for performance and predictable network costs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operational reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>CI\/CD-friendly:<\/strong> Fits naturally into pipelines; ACR Tasks can offload builds to Azure.<\/li>\n<li><strong>Eventing:<\/strong> Webhooks allow downstream automation on push\/pull events.<\/li>\n<li><strong>Monitoring &amp; logs:<\/strong> Integrates with Azure Monitor diagnostics for auditing and troubleshooting.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/compliance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Identity-based access:<\/strong> Fine-grained access via Azure RBAC (and potentially additional registry-scoped constructs depending on SKU).<\/li>\n<li><strong>Private networking options:<\/strong> Support restricting exposure so registry traffic stays on private IP space (SKU\/region dependent\u2014verify).<\/li>\n<li><strong>Auditing:<\/strong> Diagnostic logs can capture authentication and repository events for investigations and compliance.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Scalability\/performance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Managed scaling:<\/strong> Azure operates the service; you select a SKU with performance characteristics appropriate to your workload.<\/li>\n<li><strong>Enterprise features:<\/strong> Premium options like geo-replication (and related capabilities) support multi-region deployments (Premium feature; verify details).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should choose Azure Container Registry<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You deploy containers on <strong>AKS<\/strong>, <strong>Container Apps<\/strong>, or <strong>ACI<\/strong> and want Azure-native integration.<\/li>\n<li>You need <strong>private image hosting<\/strong> with Entra ID + Azure RBAC and enterprise networking.<\/li>\n<li>You want build automation using <strong>ACR Tasks<\/strong> or seamless integration with Azure DevOps\/GitHub.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should not choose it<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You don\u2019t need private hosting and are satisfied with a public registry for non-sensitive development images.<\/li>\n<li>Your organization is committed to a cross-cloud artifact platform and wants one registry for all clouds (you might prefer a neutral product like Harbor, Artifactory, or a multi-cloud artifact registry strategy).<\/li>\n<li>You require features that may be better served by a broader artifact product (e.g., a universal artifact repository for many package types, not just OCI images\/artifacts). In Azure, <strong>Azure Artifacts<\/strong> serves different use cases and is not a container registry.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">4. Where is Azure Container Registry used?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Industries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SaaS and software<\/strong>: microservices, API platforms, internal developer platforms.<\/li>\n<li><strong>Finance and healthcare<\/strong>: stronger governance, private networking, audit trails.<\/li>\n<li><strong>Retail and media<\/strong>: high deployment frequency and multi-environment pipelines.<\/li>\n<li><strong>Manufacturing\/IoT\/edge<\/strong>: edge deployments can use patterns like connected registries (where applicable; verify SKU requirements).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Team types<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Platform engineering teams building internal container platforms<\/li>\n<li>DevOps and SRE teams managing CI\/CD and runtime reliability<\/li>\n<li>Security teams enforcing supply-chain controls<\/li>\n<li>Application teams packaging services as containers<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Workloads and architectures<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Microservices on AKS<\/li>\n<li>Event-driven apps on Azure Container Apps<\/li>\n<li>Batch or short-lived tasks on Azure Container Instances<\/li>\n<li>Hybrid patterns where images are built in Azure but deployed elsewhere (on-prem Kubernetes)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world deployment contexts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Dev\/test:<\/strong> smaller SKUs, fewer retention and replication needs, flexible access for developers.<\/li>\n<li><strong>Production:<\/strong> stronger access controls, private networking, monitoring, retention policies, and multi-region strategies.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. Top Use Cases and Scenarios<\/h2>\n\n\n\n<p>Below are practical scenarios where Azure Container Registry is commonly used in real projects.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Private image hosting for AKS<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Public registries add risk, throttling, and access sprawl.<\/li>\n<li><strong>Why ACR fits:<\/strong> Tight AKS integration, Entra ID auth, Azure RBAC, private networking options.<\/li>\n<li><strong>Example:<\/strong> An AKS cluster pulls <code>payments\/api:1.9.0<\/code> from <code>companyacr.azurecr.io<\/code> using AcrPull permissions.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) CI\/CD pipeline artifact hub<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Need a consistent place to store artifacts produced by builds.<\/li>\n<li><strong>Why ACR fits:<\/strong> Standard push\/pull; integrates with GitHub Actions and Azure DevOps.<\/li>\n<li><strong>Example:<\/strong> GitHub Actions builds on every merge to <code>main<\/code> and pushes <code>webapp:&lt;git-sha&gt;<\/code> to ACR; release pipeline deploys by digest.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Cloud-based container builds with ACR Tasks<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Developers don\u2019t want to run Docker builds locally; build agents may be constrained.<\/li>\n<li><strong>Why ACR fits:<\/strong> ACR Tasks builds images in Azure; supports triggers.<\/li>\n<li><strong>Example:<\/strong> A task rebuilds an image whenever a base image changes (base image update trigger).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Multi-environment promotion (dev \u2192 staging \u2192 prod)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Tagging and promoting images consistently is error-prone.<\/li>\n<li><strong>Why ACR fits:<\/strong> One registry with repositories\/tags; promotion via immutable digests and controlled permissions.<\/li>\n<li><strong>Example:<\/strong> Only the release pipeline identity can retag <code>:candidate<\/code> to <code>:prod<\/code>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">5) Controlled access for partners or vendors<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Need to share a subset of images without giving broad access.<\/li>\n<li><strong>Why ACR fits:<\/strong> You can scope access using RBAC and (depending on SKU) more granular constructs like scope maps\/tokens\u2014verify requirements.<\/li>\n<li><strong>Example:<\/strong> External vendor gets pull-only access to <code>partner\/*<\/code> repositories.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6) Internal platform \u201cgolden images\u201d<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Teams need secure base images (hardened OS, approved runtime).<\/li>\n<li><strong>Why ACR fits:<\/strong> Central store with policy and security scanning integrations.<\/li>\n<li><strong>Example:<\/strong> Platform team maintains <code>base\/dotnet:8-alpine-hardened<\/code> consumed by all services.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">7) Import images from upstream registries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Need to mirror upstream images to reduce external dependency and improve performance.<\/li>\n<li><strong>Why ACR fits:<\/strong> Import workflows can copy images into ACR (e.g., from Docker Hub or other registries).<\/li>\n<li><strong>Example:<\/strong> Nightly import mirrors <code>nginx:stable<\/code> into <code>companyacr.azurecr.io\/mirror\/nginx:stable<\/code>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">8) Webhook-driven automation<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Need automated actions when images are pushed.<\/li>\n<li><strong>Why ACR fits:<\/strong> Webhooks can notify external systems on push events.<\/li>\n<li><strong>Example:<\/strong> On push to <code>release\/*<\/code>, a webhook triggers a deployment orchestrator.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9) Edge and disconnected scenarios (where supported)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Remote sites have limited connectivity and need local image distribution.<\/li>\n<li><strong>Why ACR fits:<\/strong> Connected registry patterns can provide local presence (SKU-dependent; verify).<\/li>\n<li><strong>Example:<\/strong> Retail stores sync a subset of images locally to keep deployments fast and resilient.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">10) Multi-region deployment performance optimization<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Global applications need fast pulls in multiple regions.<\/li>\n<li><strong>Why ACR fits:<\/strong> Geo-replication (Premium) can replicate content closer to clusters.<\/li>\n<li><strong>Example:<\/strong> AKS clusters in East US and West Europe pull from their nearest ACR replica.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">11) Compliance-driven auditing of image access<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Need to know who pulled what and when.<\/li>\n<li><strong>Why ACR fits:<\/strong> Diagnostic logs can capture login and repository events.<\/li>\n<li><strong>Example:<\/strong> Security team queries Log Analytics for pull events during an incident response.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">12) Migration from self-hosted Docker Registry<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Maintaining self-hosted registry infrastructure is operationally heavy.<\/li>\n<li><strong>Why ACR fits:<\/strong> Managed service with Azure governance and scaling.<\/li>\n<li><strong>Example:<\/strong> Move from a VM-hosted registry to ACR, then update Kubernetes imagePullSecrets \/ identities.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">6. Core Features<\/h2>\n\n\n\n<p>This section focuses on important current capabilities. Some capabilities are <strong>SKU- or region-dependent<\/strong>\u2014verify details in official docs for your environment.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Managed private registry (OCI\/Docker distribution)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Stores and serves images and OCI artifacts via standard registry APIs.<\/li>\n<li><strong>Why it matters:<\/strong> Standard tooling works; fewer bespoke integrations.<\/li>\n<li><strong>Practical benefit:<\/strong> Developers can use <code>docker push<\/code>\/<code>docker pull<\/code> (or Podman) with minimal changes.<\/li>\n<li><strong>Caveats:<\/strong> Throughput\/performance and certain advanced features vary by SKU.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Multiple SKUs (Basic \/ Standard \/ Premium)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Provides tiered capacity\/performance and advanced capabilities.<\/li>\n<li><strong>Why it matters:<\/strong> Lets you align cost and features with environment needs.<\/li>\n<li><strong>Practical benefit:<\/strong> Use Basic for dev\/test; use Premium for multi-region, advanced networking, and enterprise governance.<\/li>\n<li><strong>Caveats:<\/strong> Feature availability (replication, tokens\/scope maps, private networking options, retention features) can differ\u2014verify in docs and pricing page.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Microsoft Entra ID authentication + Azure RBAC authorization<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Uses Entra ID identities (users, groups, service principals, managed identities) and Azure RBAC roles like <code>AcrPull<\/code> \/ <code>AcrPush<\/code>.<\/li>\n<li><strong>Why it matters:<\/strong> Central identity governance, conditional access, least privilege.<\/li>\n<li><strong>Practical benefit:<\/strong> AKS\/ACI can pull without embedding static passwords if configured with managed identities or cluster integration.<\/li>\n<li><strong>Caveats:<\/strong> Some scenarios still use imagePullSecrets or admin user credentials; avoid for production when possible.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Admin user (username\/password) option<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Enables a static credential pair for the registry.<\/li>\n<li><strong>Why it matters:<\/strong> Simple for quick tests and some legacy tooling.<\/li>\n<li><strong>Practical benefit:<\/strong> Fast onboarding for labs.<\/li>\n<li><strong>Caveats:<\/strong> Not recommended for production; harder to rotate and audit; prefer Entra ID and managed identities.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">ACR Tasks (cloud builds and automation)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Builds container images in Azure and can run tasks triggered by commits, base image updates, or schedules.<\/li>\n<li><strong>Why it matters:<\/strong> Offloads build infrastructure; improves reproducibility.<\/li>\n<li><strong>Practical benefit:<\/strong> Build images without installing Docker locally; consistent builds in controlled environment.<\/li>\n<li><strong>Caveats:<\/strong> Task pricing is separate from registry storage; build context size and network access patterns matter. Verify current ACR Tasks billing on pricing page.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Webhooks<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Sends HTTP callbacks on registry events (e.g., push).<\/li>\n<li><strong>Why it matters:<\/strong> Enables event-driven pipelines and integrations.<\/li>\n<li><strong>Practical benefit:<\/strong> Trigger deployments, scans, notifications, or metadata updates.<\/li>\n<li><strong>Caveats:<\/strong> Webhook endpoints must be reachable and secured; consider retries and idempotency.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Geo-replication (Premium)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Replicates registry content to additional regions for local pulls.<\/li>\n<li><strong>Why it matters:<\/strong> Reduces latency and cross-region egress; improves resilience.<\/li>\n<li><strong>Practical benefit:<\/strong> Multi-region AKS clusters pull from nearest replica.<\/li>\n<li><strong>Caveats:<\/strong> Premium only; replication adds cost and operational considerations (regional availability, failover patterns). Verify in docs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Private connectivity and network controls<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Options to reduce public exposure (for example, private endpoints) and restrict inbound access (firewall rules).<\/li>\n<li><strong>Why it matters:<\/strong> Registry access is a critical supply-chain path; limiting exposure reduces attack surface.<\/li>\n<li><strong>Practical benefit:<\/strong> AKS nodes pull images over private IP, not public internet.<\/li>\n<li><strong>Caveats:<\/strong> Availability may depend on SKU and region; DNS configuration becomes important with private endpoints.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Import \/ transfer utilities<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Imports images from other registries into ACR.<\/li>\n<li><strong>Why it matters:<\/strong> Reduces dependency on external registries and stabilizes builds.<\/li>\n<li><strong>Practical benefit:<\/strong> Mirror base images and pin by digest in your own registry.<\/li>\n<li><strong>Caveats:<\/strong> Licensing and usage policies of upstream images still apply.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Retention and cleanup features (SKU-dependent)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Helps manage storage growth (e.g., retention policies for untagged manifests in some tiers).<\/li>\n<li><strong>Why it matters:<\/strong> Registries can grow quickly in CI-heavy environments.<\/li>\n<li><strong>Practical benefit:<\/strong> Reduce storage cost and clutter.<\/li>\n<li><strong>Caveats:<\/strong> Policies can delete artifacts you still need if tag strategy is weak; test in non-prod first. Verify exact policy options by SKU.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Observability: metrics and diagnostic logs<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Exposes metrics (throughput, storage, etc.) and logs (authentication, repository events) via Azure Monitor.<\/li>\n<li><strong>Why it matters:<\/strong> You need evidence for troubleshooting, auditing, and cost control.<\/li>\n<li><strong>Practical benefit:<\/strong> Alert on unusual pull patterns or auth failures; investigate who pulled a vulnerable image.<\/li>\n<li><strong>Caveats:<\/strong> Storing logs in Log Analytics or Storage has separate costs.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">7. Architecture and How It Works<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">High-level service architecture<\/h3>\n\n\n\n<p>At a high level:\n1. A developer or CI system authenticates to ACR.\n2. The build system pushes an image (layers + manifest) to a repository.\n3. A runtime (AKS\/Container Apps\/ACI) authenticates and pulls the image by tag or digest.\n4. Logs and metrics flow to Azure Monitor if diagnostics are enabled.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Request\/data\/control flow<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Control plane:<\/strong> Azure Resource Manager (ARM) manages the ACR resource (create registry, configure networking, enable admin user, manage replications, configure diagnostics).<\/li>\n<li><strong>Data plane:<\/strong> Docker\/OCI registry API traffic for pushing\/pulling layers and manifests.<\/li>\n<li><strong>Identity:<\/strong> Entra ID issues tokens; Azure RBAC authorizes operations (push\/pull\/delete depending on role).<\/li>\n<li><strong>Eventing:<\/strong> Webhooks post events to external endpoints (e.g., a deployment service).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Integrations with related Azure services<\/h3>\n\n\n\n<p>Common integrations include:\n&#8211; <strong>AKS<\/strong>: attach ACR, or grant AcrPull to kubelet identity \/ managed identity.\n&#8211; <strong>Azure Container Apps<\/strong>: pull images from ACR; typically uses managed identity or registry credentials depending on setup.\n&#8211; <strong>Azure Container Instances<\/strong>: run a container directly from ACR.\n&#8211; <strong>Azure DevOps \/ GitHub Actions<\/strong>: build and push images.\n&#8211; <strong>Azure Key Vault<\/strong>: for customer-managed keys (if enabled\/supported) and for pipeline secret management.\n&#8211; <strong>Azure Monitor \/ Log Analytics<\/strong>: store and query logs, create alerts.\n&#8211; <strong>Microsoft Defender for Cloud<\/strong>: container registry security posture and vulnerability scanning plans (capabilities and licensing vary\u2014verify in Defender documentation).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dependency services (conceptual)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Microsoft Entra ID (identity)<\/li>\n<li>Azure Resource Manager (management)<\/li>\n<li>Azure Monitor (observability)<\/li>\n<li>Azure networking (Private Link\/private endpoints, DNS, firewalls\u2014where used)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/authentication model (practical)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Preferred: <strong>Entra ID + Azure RBAC<\/strong> with <strong>managed identities<\/strong> for workloads.<\/li>\n<li>Alternative: <strong>Service principals<\/strong> for CI\/CD (with least privilege and secret rotation).<\/li>\n<li>Fallback\/lab: <strong>admin user<\/strong> credentials (avoid for production).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Networking model (practical)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Default: public registry endpoint protected by auth.<\/li>\n<li>Hardened: limit access via firewall rules and\/or use private endpoints (where supported), then ensure private DNS resolution for <code>*.azurecr.io<\/code> (and any relevant data endpoints depending on your configuration).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Monitoring\/logging\/governance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable <strong>diagnostic settings<\/strong> to send logs to Log Analytics for:<\/li>\n<li>authentication\/login events<\/li>\n<li>repository events (push\/pull\/delete)<\/li>\n<li>Add <strong>Azure Policy<\/strong> guardrails:<\/li>\n<li>enforce private endpoints (where required)<\/li>\n<li>enforce tags and naming conventions<\/li>\n<li>restrict creation to approved regions\/SKUs<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Simple architecture diagram (Mermaid)<\/h4>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart LR\n  Dev[Developer or CI] --&gt;|docker push| ACR[Azure Container Registry]\n  ACR --&gt;|docker pull| Runtime[AKS \/ Container Apps \/ ACI]\n  Dev --&gt;|Entra ID auth| Entra[Microsoft Entra ID]\n  Runtime --&gt;|Entra ID token| Entra\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Production-style architecture diagram (Mermaid)<\/h4>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart TB\n  subgraph DevSecOps\n    Code[Git repo] --&gt; Pipeline[CI Pipeline\\n(GitHub Actions\/Azure DevOps)]\n    Pipeline --&gt;|Build &amp; push| ACR[(Azure Container Registry)]\n    ACR --&gt; Webhook[Webhook to CD\/Automation]\n  end\n\n  subgraph Security\n    Defender[Microsoft Defender for Cloud\\n(Container Registry plan)\\nVerify capabilities] --&gt; ACR\n    Policy[Azure Policy] --&gt; ACR\n    Logs[Azure Monitor + Log Analytics] &lt;--&gt;|Diagnostics| ACR\n  end\n\n  subgraph Network\n    PE[Private Endpoint\\n(if enabled)] --- ACR\n    DNS[Private DNS Zone] --- PE\n  end\n\n  subgraph Runtime\n    AKS1[AKS Cluster - Region A] --&gt;|Pull by digest| ACR\n    AKS2[AKS Cluster - Region B] --&gt;|Pull from replica| ACR\n  end\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">8. Prerequisites<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Azure account and subscription<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An <strong>active Azure subscription<\/strong> with billing enabled.<\/li>\n<li>Permission to create resources in a resource group.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Permissions \/ IAM roles<\/h3>\n\n\n\n<p>You typically need one of:\n&#8211; <code>Owner<\/code> or <code>Contributor<\/code> on the subscription\/resource group to create the registry, or\n&#8211; Fine-grained permissions to create <code>Microsoft.ContainerRegistry\/registries<\/code>.<\/p>\n\n\n\n<p>For pushing\/pulling images:\n&#8211; Use built-in roles:\n  &#8211; <strong>AcrPull<\/strong>: pull images\n  &#8211; <strong>AcrPush<\/strong>: push\/pull images\n  &#8211; <strong>Owner\/Contributor<\/strong>: includes broader rights (avoid granting broadly in production)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tools<\/h3>\n\n\n\n<p>Choose one of these environments:\n&#8211; <strong>Azure Cloud Shell<\/strong> (has Azure CLI; Docker may not be available)\n&#8211; Local machine:\n  &#8211; <strong>Azure CLI<\/strong> (<code>az<\/code>) \u2013 https:\/\/learn.microsoft.com\/cli\/azure\/install-azure-cli\n  &#8211; <strong>Docker Desktop<\/strong> or <strong>Docker Engine<\/strong>, or <strong>Podman<\/strong>\n  &#8211; Optional: <code>kubectl<\/code> (if integrating with AKS), Git<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Region availability<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ACR is available in many Azure regions. Advanced capabilities (geo-replication, zone redundancy, some networking features) can vary by region and SKU. <strong>Verify in official docs<\/strong>:<\/li>\n<li>https:\/\/learn.microsoft.com\/azure\/container-registry\/<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Quotas and limits (high level)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Registry name must be globally unique (under <code>*.azurecr.io<\/code>) and follow naming rules.<\/li>\n<li>Throughput, storage, webhook limits, and replication limits depend on SKU. <strong>Check the current limits page<\/strong> in official docs before production rollout.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisite services (for this lab)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A resource group<\/li>\n<li>Azure Container Registry<\/li>\n<li>Docker\/Podman locally (recommended for the hands-on steps below)<\/li>\n<li>Optional for \u201crun it\u201d verification: Azure Container Instances<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">9. Pricing \/ Cost<\/h2>\n\n\n\n<p>Azure Container Registry pricing is <strong>SKU-based plus usage-based<\/strong>. Exact prices vary by <strong>region<\/strong>, <strong>SKU<\/strong>, and sometimes by feature usage. Always validate with:\n&#8211; Official pricing page: https:\/\/azure.microsoft.com\/pricing\/details\/container-registry\/\n&#8211; Azure Pricing Calculator: https:\/\/azure.microsoft.com\/pricing\/calculator\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pricing dimensions (typical)<\/h3>\n\n\n\n<p>Common cost components include:\n1. <strong>Registry SKU (Basic \/ Standard \/ Premium)<\/strong>\n   &#8211; Determines included capabilities and performance profile.\n2. <strong>Storage<\/strong>\n   &#8211; Stored image layers\/manifests consume storage over time.\n   &#8211; CI systems can create many tags\/digests; storage growth is a primary driver.\n3. <strong>Data transfer<\/strong>\n   &#8211; Pulling images across regions or to the internet can incur egress costs.\n   &#8211; Pulling from ACR to compute in the same region can be cheaper than cross-region pulls (depending on your architecture).\n4. <strong>Build automation (ACR Tasks)<\/strong>\n   &#8211; If you use ACR Tasks, builds are billed separately based on the tasks pricing model (compute time\/resources). Verify current billing details on the pricing page.\n5. <strong>Premium features that scale with usage<\/strong>\n   &#8211; Geo-replication adds additional regional replicas (additional cost).\n   &#8211; Private networking features themselves may not be priced as \u201cACR add-ons,\u201d but they can create costs in dependent services (e.g., Private Endpoint and Private DNS, plus network processing). Verify current Private Link pricing in Azure networking docs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Free tier?<\/h3>\n\n\n\n<p>ACR generally does not present as a \u201cfree tier\u201d in the same way as some services; however, <strong>new Azure accounts<\/strong> sometimes have credits or free offers that can offset early usage. Verify current Azure free offerings: https:\/\/azure.microsoft.com\/free\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cost drivers (what actually moves your bill)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Number and size of images<\/strong> (multi-arch images, large base layers, debug symbols)<\/li>\n<li><strong>CI frequency<\/strong> and tag strategy (e.g., tagging every commit without retention)<\/li>\n<li><strong>Cross-region pulls<\/strong> (multi-region AKS pulling from a single region)<\/li>\n<li><strong>Geo-replication count<\/strong> (Premium)<\/li>\n<li><strong>Task build frequency<\/strong> and build context sizes (ACR Tasks)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hidden\/indirect costs<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Log Analytics ingestion<\/strong> for diagnostic logs (can be significant at high pull\/push volume).<\/li>\n<li><strong>Networking<\/strong>: egress, Private Link, DNS queries (usually small, but can add up).<\/li>\n<li><strong>Security scanning<\/strong>: Microsoft Defender for Cloud plans are billed separately.<\/li>\n<li><strong>Developer tooling<\/strong>: build agents, runners, and storage for pipeline artifacts.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How to optimize cost<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Keep registry and compute <strong>in the same region<\/strong> when possible.<\/li>\n<li>Prefer <strong>small base images<\/strong> and multi-stage builds.<\/li>\n<li>Implement a <strong>tagging and retention strategy<\/strong>:<\/li>\n<li>Keep immutable release tags<\/li>\n<li>Clean up ephemeral CI tags<\/li>\n<li>Consider SKU features for retention policies (verify availability)<\/li>\n<li>Use <strong>image digests<\/strong> for deployments to avoid accidental re-pulls of mutated tags.<\/li>\n<li>If multi-region: evaluate <strong>geo-replication<\/strong> vs. cross-region pulls and egress.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Example low-cost starter estimate (no fabricated numbers)<\/h3>\n\n\n\n<p>A low-cost dev\/test setup usually looks like:\n&#8211; One <strong>Basic<\/strong> registry\n&#8211; Minimal image set (a few services)\n&#8211; No geo-replication\n&#8211; Limited diagnostic logging (or short retention)<\/p>\n\n\n\n<p>To estimate:\n1. Pick your region and SKU on the official pricing page.\n2. Estimate storage: total GB stored (images + tags you keep).\n3. Estimate pulls\/pushes and egress if any.\n4. Add ACR Tasks if you use them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example production cost considerations<\/h3>\n\n\n\n<p>Production environments commonly add:\n&#8211; <strong>Standard or Premium<\/strong> SKU\n&#8211; <strong>Private networking<\/strong>\n&#8211; <strong>Geo-replication<\/strong> (Premium) for multi-region clusters\n&#8211; <strong>Diagnostic logs<\/strong> to Log Analytics with retention policies\n&#8211; <strong>Defender for Cloud<\/strong> plans<\/p>\n\n\n\n<p>In production, the biggest surprises are often:\n&#8211; Unbounded registry storage due to CI tags\n&#8211; Cross-region or internet egress due to topology\n&#8211; Log Analytics ingestion volumes<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Step-by-Step Hands-On Tutorial<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Objective<\/h3>\n\n\n\n<p>Create an Azure Container Registry, build a container image, push it to Azure Container Registry, then pull and run it to confirm end-to-end functionality. Optionally, run it in Azure Container Instances to validate registry-to-runtime integration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab Overview<\/h3>\n\n\n\n<p>You will:\n1. Create a resource group and an <strong>Azure Container Registry (Basic)<\/strong>.\n2. Authenticate to the registry using Entra ID (<code>az acr login<\/code>).\n3. Build a small container image locally (or adapt to ACR Tasks if you prefer).\n4. Tag and push the image to Azure Container Registry.\n5. Verify the repository and tags in ACR.\n6. (Optional) Run the container in <strong>Azure Container Instances<\/strong> using registry credentials.\n7. Clean up all resources.<\/p>\n\n\n\n<p><strong>Expected cost:<\/strong> Low for a short lab, but not zero. Storage and any ACI runtime minutes will incur charges. Always delete resources when finished.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Set variables and create a resource group<\/h3>\n\n\n\n<p>On your machine (or Cloud Shell), sign in:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az login\naz account show\n<\/code><\/pre>\n\n\n\n<p>Set variables (adjust region as needed):<\/p>\n\n\n\n<pre><code class=\"language-bash\">RG=\"rg-acr-lab\"\nLOCATION=\"eastus\"\nACR_NAME=\"acr$(date +%s)\"   # makes a mostly-unique name; must be globally unique\n<\/code><\/pre>\n\n\n\n<p>Create the resource group:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group create --name \"$RG\" --location \"$LOCATION\"\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> A resource group exists in your chosen region.<\/p>\n\n\n\n<p>Verify:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group show --name \"$RG\" --query \"{name:name, location:location}\" -o table\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Create Azure Container Registry (Basic)<\/h3>\n\n\n\n<p>Create the registry:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az acr create \\\n  --resource-group \"$RG\" \\\n  --name \"$ACR_NAME\" \\\n  --sku Basic \\\n  --admin-enabled false\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> ACR is created and ready to accept pushes.<\/p>\n\n\n\n<p>Verify:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az acr show --resource-group \"$RG\" --name \"$ACR_NAME\" \\\n  --query \"{name:name, loginServer:loginServer, sku:sku.name, provisioningState:provisioningState}\" -o table\n<\/code><\/pre>\n\n\n\n<p>Capture the login server:<\/p>\n\n\n\n<pre><code class=\"language-bash\">LOGIN_SERVER=\"$(az acr show -g \"$RG\" -n \"$ACR_NAME\" --query loginServer -o tsv)\"\necho \"$LOGIN_SERVER\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Authenticate to Azure Container Registry<\/h3>\n\n\n\n<p>Login using Entra ID:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az acr login --name \"$ACR_NAME\"\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> Your Docker\/Podman client can authenticate to the registry.<\/p>\n\n\n\n<p>Verification idea (Docker):<\/p>\n\n\n\n<pre><code class=\"language-bash\">docker logout \"$LOGIN_SERVER\" 2&gt;\/dev\/null || true\naz acr login --name \"$ACR_NAME\"\n<\/code><\/pre>\n\n\n\n<p>If you use Podman, you can often login with:<\/p>\n\n\n\n<pre><code class=\"language-bash\">podman login \"$LOGIN_SERVER\"\n<\/code><\/pre>\n\n\n\n<p>(If Podman prompts for username\/password, you may need to use an access token or admin credentials. Behavior varies by client version. Verify in official docs if needed.)<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Build a small container image locally<\/h3>\n\n\n\n<p>Create a working folder:<\/p>\n\n\n\n<pre><code class=\"language-bash\">mkdir acr-lab &amp;&amp; cd acr-lab\n<\/code><\/pre>\n\n\n\n<p>Create a tiny web app using NGINX and a static page.<\/p>\n\n\n\n<p>Create <code>index.html<\/code>:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cat &gt; index.html &lt;&lt;'EOF'\n&lt;!doctype html&gt;\n&lt;html&gt;\n  &lt;head&gt;&lt;meta charset=\"utf-8\"&gt;&lt;title&gt;ACR Lab&lt;\/title&gt;&lt;\/head&gt;\n  &lt;body&gt;\n    &lt;h1&gt;Hello from Azure Container Registry&lt;\/h1&gt;\n    &lt;p&gt;If you can read this, your image build\/push\/pull worked.&lt;\/p&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;\nEOF\n<\/code><\/pre>\n\n\n\n<p>Create <code>Dockerfile<\/code>:<\/p>\n\n\n\n<pre><code class=\"language-dockerfile\">FROM nginx:alpine\nCOPY index.html \/usr\/share\/nginx\/html\/index.html\n<\/code><\/pre>\n\n\n\n<p>Build:<\/p>\n\n\n\n<pre><code class=\"language-bash\">IMAGE_REPO=\"samples\/hello-acr\"\nIMAGE_TAG=\"v1\"\ndocker build -t \"${IMAGE_REPO}:${IMAGE_TAG}\" .\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> A local image exists.<\/p>\n\n\n\n<p>Verify:<\/p>\n\n\n\n<pre><code class=\"language-bash\">docker images | head\ndocker inspect \"${IMAGE_REPO}:${IMAGE_TAG}\" --format='{{.Id}}'\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Tag and push the image to Azure Container Registry<\/h3>\n\n\n\n<p>Tag the image with your ACR login server:<\/p>\n\n\n\n<pre><code class=\"language-bash\">docker tag \"${IMAGE_REPO}:${IMAGE_TAG}\" \"${LOGIN_SERVER}\/${IMAGE_REPO}:${IMAGE_TAG}\"\n<\/code><\/pre>\n\n\n\n<p>Push:<\/p>\n\n\n\n<pre><code class=\"language-bash\">docker push \"${LOGIN_SERVER}\/${IMAGE_REPO}:${IMAGE_TAG}\"\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> The image is uploaded to Azure Container Registry.<\/p>\n\n\n\n<p>Verify in ACR:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az acr repository list --name \"$ACR_NAME\" -o table\naz acr repository show-tags --name \"$ACR_NAME\" --repository \"$IMAGE_REPO\" -o table\n<\/code><\/pre>\n\n\n\n<p>You can also view manifests (useful for digest-based deployments):<\/p>\n\n\n\n<pre><code class=\"language-bash\">az acr repository show-manifests --name \"$ACR_NAME\" --repository \"$IMAGE_REPO\" -o table\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6 (Optional but recommended): Pull from ACR and run locally<\/h3>\n\n\n\n<p>Remove your local tagged copy to prove it pulls from ACR:<\/p>\n\n\n\n<pre><code class=\"language-bash\">docker rmi \"${LOGIN_SERVER}\/${IMAGE_REPO}:${IMAGE_TAG}\" || true\ndocker pull \"${LOGIN_SERVER}\/${IMAGE_REPO}:${IMAGE_TAG}\"\n<\/code><\/pre>\n\n\n\n<p>Run it:<\/p>\n\n\n\n<pre><code class=\"language-bash\">docker run --rm -d -p 8080:80 --name hello-acr \"${LOGIN_SERVER}\/${IMAGE_REPO}:${IMAGE_TAG}\"\n<\/code><\/pre>\n\n\n\n<p>Test:<\/p>\n\n\n\n<pre><code class=\"language-bash\">curl -i http:\/\/localhost:8080 | head -n 20\n<\/code><\/pre>\n\n\n\n<p>Stop:<\/p>\n\n\n\n<pre><code class=\"language-bash\">docker stop hello-acr\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> You see an HTTP 200 response and your \u201cHello from Azure Container Registry\u201d page.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7 (Optional): Run the image in Azure Container Instances (ACI)<\/h3>\n\n\n\n<p>This demonstrates a managed runtime pulling from ACR. For a simple lab, the fastest path is to enable the ACR admin user temporarily (not recommended for production).<\/p>\n\n\n\n<p>Enable admin user:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az acr update --name \"$ACR_NAME\" --admin-enabled true\n<\/code><\/pre>\n\n\n\n<p>Fetch credentials:<\/p>\n\n\n\n<pre><code class=\"language-bash\">ACR_USER=\"$(az acr credential show -n \"$ACR_NAME\" --query username -o tsv)\"\nACR_PASS=\"$(az acr credential show -n \"$ACR_NAME\" --query passwords[0].value -o tsv)\"\n<\/code><\/pre>\n\n\n\n<p>Create a container group:<\/p>\n\n\n\n<pre><code class=\"language-bash\">ACI_NAME=\"aci-hello-acr\"\nDNS_LABEL=\"helloacr$RANDOM\"\n\naz container create \\\n  --resource-group \"$RG\" \\\n  --name \"$ACI_NAME\" \\\n  --image \"${LOGIN_SERVER}\/${IMAGE_REPO}:${IMAGE_TAG}\" \\\n  --registry-login-server \"$LOGIN_SERVER\" \\\n  --registry-username \"$ACR_USER\" \\\n  --registry-password \"$ACR_PASS\" \\\n  --dns-name-label \"$DNS_LABEL\" \\\n  --ports 80\n<\/code><\/pre>\n\n\n\n<p>Get its FQDN:<\/p>\n\n\n\n<pre><code class=\"language-bash\">FQDN=\"$(az container show -g \"$RG\" -n \"$ACI_NAME\" --query ipAddress.fqdn -o tsv)\"\necho \"http:\/\/$FQDN\"\n<\/code><\/pre>\n\n\n\n<p>Test:<\/p>\n\n\n\n<pre><code class=\"language-bash\">curl -i \"http:\/\/$FQDN\" | head -n 20\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> The ACI instance serves the same HTML page, proving ACI can pull from your ACR.<\/p>\n\n\n\n<p>Security note: After the test, disable admin user again:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az acr update --name \"$ACR_NAME\" --admin-enabled false\n<\/code><\/pre>\n\n\n\n<p>A production approach would use managed identity and AcrPull role assignment where supported\u2014verify current ACI + ACR identity features in official docs.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Validation<\/h3>\n\n\n\n<p>Use this checklist:\n&#8211; <code>az acr show<\/code> returns your registry and login server.\n&#8211; <code>az acr repository list<\/code> shows <code>samples\/hello-acr<\/code>.\n&#8211; <code>az acr repository show-tags<\/code> shows <code>v1<\/code>.\n&#8211; <code>docker pull &lt;loginServer&gt;\/samples\/hello-acr:v1<\/code> succeeds.\n&#8211; (Optional) ACI endpoint returns HTTP 200 and the expected content.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Troubleshooting<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Problem: <code>az acr login<\/code> succeeds but <code>docker push<\/code> fails with unauthorized<\/h4>\n\n\n\n<p>Common causes:\n&#8211; Docker is using a different credential store context than expected.\n&#8211; You are signed into the wrong Azure subscription\/tenant.<\/p>\n\n\n\n<p>Fixes:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az account show -o table\naz account set --subscription \"&lt;your-subscription-id&gt;\"\naz acr login --name \"$ACR_NAME\"\ndocker logout \"$LOGIN_SERVER\"\naz acr login --name \"$ACR_NAME\"\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Problem: Registry name is not available<\/h4>\n\n\n\n<p>ACR names must be globally unique.\n&#8211; Choose another name and re-run creation.\n&#8211; Avoid uppercase and special characters.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Problem: ACI fails to pull image<\/h4>\n\n\n\n<p>Common causes:\n&#8211; Wrong registry server, username, or password.\n&#8211; Image name mismatch (repository path differs).<\/p>\n\n\n\n<p>Fix:\n&#8211; Confirm image exists:\n  <code>bash\n  az acr repository list --name \"$ACR_NAME\" -o table<\/code>\n&#8211; Confirm exact image reference:\n  <code>bash\n  echo \"${LOGIN_SERVER}\/${IMAGE_REPO}:${IMAGE_TAG}\"<\/code>\n&#8211; Check ACI events\/logs:\n  <code>bash\n  az container logs -g \"$RG\" -n \"$ACI_NAME\"\n  az container show -g \"$RG\" -n \"$ACI_NAME\" --query instanceView.events -o table<\/code><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Problem: <code>curl<\/code> to ACI FQDN times out<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The container group may still be provisioning.<\/li>\n<li>Corporate firewall might block outbound HTTP.<\/li>\n<\/ul>\n\n\n\n<p>Fix:\n&#8211; Wait and retry.\n&#8211; Check the IP and FQDN:\n  <code>bash\n  az container show -g \"$RG\" -n \"$ACI_NAME\" --query ipAddress -o json<\/code><\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Cleanup<\/h3>\n\n\n\n<p>Delete the resource group (removes registry and optional ACI):<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group delete --name \"$RG\" --yes --no-wait\n<\/code><\/pre>\n\n\n\n<p>If you created local files, delete them:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cd .. &amp;&amp; rm -rf acr-lab\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">11. Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Architecture best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Keep registry close to compute<\/strong> (same region as AKS\/Container Apps) to reduce latency and egress.<\/li>\n<li><strong>Use digest-based deployments<\/strong> in production (<code>image@sha256:...<\/code>) to guarantee immutability.<\/li>\n<li>For multi-region apps:<\/li>\n<li>Consider <strong>geo-replication<\/strong> (Premium) to avoid cross-region pulls.<\/li>\n<li>Design failover patterns intentionally (verify replica behavior and operational procedures).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">IAM\/security best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prefer <strong>managed identities<\/strong> for Azure-hosted runtimes.<\/li>\n<li>For CI\/CD:<\/li>\n<li>Use a dedicated <strong>service principal<\/strong> with <strong>AcrPush<\/strong> to specific registries.<\/li>\n<li>Store secrets in <strong>Azure Key Vault<\/strong> or GitHub\/Azure DevOps secret stores.<\/li>\n<li>Rotate credentials and limit scope.<\/li>\n<li>Avoid enabling <strong>admin user<\/strong> in production.<\/li>\n<li>Use <strong>least privilege<\/strong>: runtime should typically have <strong>AcrPull<\/strong> only.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Cost best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Implement <strong>retention policies<\/strong> (where supported) and delete unused tags regularly.<\/li>\n<li>Avoid storing large, duplicate images:<\/li>\n<li>Use shared base images<\/li>\n<li>Use multi-stage builds<\/li>\n<li>Control log volume:<\/li>\n<li>Enable diagnostics intentionally<\/li>\n<li>Apply Log Analytics retention policies<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use smaller images; remove build-time dependencies.<\/li>\n<li>Keep pull paths short and avoid unnecessary layers.<\/li>\n<li>Consider Premium throughput for heavy CI\/CD and high pull volume.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Reliability best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Treat your registry as a <strong>critical dependency<\/strong> in your delivery chain.<\/li>\n<li>Document recovery steps:<\/li>\n<li>Rebuild images from source if needed<\/li>\n<li>Mirror critical base images<\/li>\n<li>For mission-critical workloads, evaluate multi-region strategies (Premium geo-replication).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operations best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable <strong>diagnostic settings<\/strong> and create alerts for:<\/li>\n<li>spikes in <code>401\/403<\/code> (auth failures)<\/li>\n<li>unusual pull volumes<\/li>\n<li>Standardize naming:<\/li>\n<li>Registry: <code>acr-&lt;org&gt;-&lt;env&gt;-&lt;region&gt;<\/code><\/li>\n<li>Repos: <code>&lt;domain&gt;\/&lt;service&gt;<\/code><\/li>\n<li>Tags: semantic version + git SHA, avoid mutable <code>latest<\/code> in production<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Governance\/tagging\/naming best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Apply Azure tags to the registry resource:<\/li>\n<li><code>env=dev|staging|prod<\/code><\/li>\n<li><code>costCenter=...<\/code><\/li>\n<li><code>owner=...<\/code><\/li>\n<li>Use Azure Policy (where appropriate) to enforce:<\/li>\n<li>approved SKUs<\/li>\n<li>private access requirements<\/li>\n<li>diagnostic settings enabled<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">12. Security Considerations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Identity and access model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Entra ID + Azure RBAC<\/strong> is the recommended model.<\/li>\n<li>Common roles:<\/li>\n<li><code>AcrPull<\/code> for runtime<\/li>\n<li><code>AcrPush<\/code> for build pipelines<\/li>\n<li>Consider separating registries by environment (dev\/prod) to reduce blast radius.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Encryption<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>In transit:<\/strong> TLS is used for registry traffic.<\/li>\n<li><strong>At rest:<\/strong> ACR data is encrypted at rest by Azure. Options such as customer-managed keys may be available depending on SKU\/region\u2014<strong>verify in official docs<\/strong>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Network exposure<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Default registry endpoints are reachable publicly but require auth.<\/li>\n<li>For stricter postures:<\/li>\n<li>Use <strong>private endpoints<\/strong> (where supported) and restrict public network access.<\/li>\n<li>Ensure DNS is correct (private DNS zones\/records).<\/li>\n<li>Use firewall rules where applicable.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secrets handling<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Avoid embedding registry passwords in:<\/li>\n<li>container images<\/li>\n<li>source code<\/li>\n<li>Kubernetes manifests checked into Git<\/li>\n<li>Prefer:<\/li>\n<li>managed identity pulls<\/li>\n<li>workload identity patterns (AKS) where applicable<\/li>\n<li>secret stores (Key Vault, external secrets operators) when static creds are unavoidable<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Audit\/logging<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable diagnostic logs to capture:<\/li>\n<li>login\/auth events<\/li>\n<li>repository events<\/li>\n<li>Route to Log Analytics for query and alerting.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Compliance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ACR supports common enterprise controls (identity, logging, network restriction).<\/li>\n<li>Your compliance requirements may require:<\/li>\n<li>private networking<\/li>\n<li>key management policies<\/li>\n<li>data residency constraints (region choice)<\/li>\n<li>retention requirements for logs<\/li>\n<li>Validate against the latest Azure compliance documentation and ACR docs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Common security mistakes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Leaving <strong>admin user enabled<\/strong> permanently.<\/li>\n<li>Using a shared service principal across many pipelines and environments.<\/li>\n<li>Allowing broad <code>Owner\/Contributor<\/code> access when <code>AcrPull\/AcrPush<\/code> is enough.<\/li>\n<li>Deploying with mutable tags like <code>latest<\/code> (hard to audit what actually ran).<\/li>\n<li>No logging\/diagnostics, making incident response difficult.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secure deployment recommendations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use separate registries for <strong>prod vs non-prod<\/strong>, or at least separate repos with strict permissions.<\/li>\n<li>Require:<\/li>\n<li>private endpoints (where mandated)<\/li>\n<li>least privilege roles<\/li>\n<li>immutable tagging strategy + digest pinning<\/li>\n<li>Integrate with supply-chain controls:<\/li>\n<li>vulnerability scanning via Defender for Cloud (licensed separately)<\/li>\n<li>image signing strategy (verify current recommended tooling for ACR and OCI signing)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">13. Limitations and Gotchas<\/h2>\n\n\n\n<blockquote>\n<p>Limits and feature availability can change. Confirm current behavior in official docs before production decisions.<\/p>\n<\/blockquote>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SKU feature differences:<\/strong> Premium-only features (e.g., geo-replication) are common; some auth\/networking granularity may also depend on SKU.<\/li>\n<li><strong>Name constraints:<\/strong> Registry name must be globally unique and follow strict naming rules.<\/li>\n<li><strong>Tag sprawl:<\/strong> CI pipelines can create thousands of tags quickly, increasing storage and making cleanup hard.<\/li>\n<li><strong>Mutable tags:<\/strong> Using <code>latest<\/code> (or reusing a version tag) causes drift and breaks auditability.<\/li>\n<li><strong>Cross-region pulls:<\/strong> Pulling images from a registry in another region can add latency and data transfer cost.<\/li>\n<li><strong>Private endpoint DNS complexity:<\/strong> Private connectivity requires correct DNS resolution; misconfiguration leads to pull failures that look like auth errors.<\/li>\n<li><strong>Tooling version mismatches:<\/strong> Older Docker\/Helm\/OCI tooling may not support newer artifact patterns; verify tool versions.<\/li>\n<li><strong>Logging cost:<\/strong> Diagnostic logs to Log Analytics can be surprisingly expensive at scale.<\/li>\n<li><strong>Deletion semantics:<\/strong> Image deletion affects tags\/manifests; understand digest references so you don\u2019t break rollbacks.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">14. Comparison with Alternatives<\/h2>\n\n\n\n<p>Azure Container Registry is Azure-native, but there are good alternatives depending on your cloud, compliance posture, and ecosystem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Options to consider<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Within Azure<\/strong><\/li>\n<li>Azure Container Registry (this service) is the main managed container registry.<\/li>\n<li>GitHub Container Registry (GHCR) is common for GitHub-centric workflows (not an Azure resource).<\/li>\n<li><strong>Other clouds<\/strong><\/li>\n<li>Amazon Elastic Container Registry (ECR)<\/li>\n<li>Google Artifact Registry<\/li>\n<li><strong>Self-managed \/ third-party<\/strong><\/li>\n<li>Harbor<\/li>\n<li>JFrog Artifactory<\/li>\n<li>Sonatype Nexus Repository<\/li>\n<li>Self-hosted Docker Registry (generally not recommended for most teams unless necessary)<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Option<\/th>\n<th>Best For<\/th>\n<th>Strengths<\/th>\n<th>Weaknesses<\/th>\n<th>When to Choose<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Azure Container Registry<\/td>\n<td>Azure-hosted container platforms<\/td>\n<td>Entra ID + Azure RBAC, Azure networking, AKS integration, managed service<\/td>\n<td>Azure-specific governance and patterns; some features SKU-dependent<\/td>\n<td>You run containers on Azure and want native integration<\/td>\n<\/tr>\n<tr>\n<td>GitHub Container Registry (GHCR)<\/td>\n<td>GitHub-first teams<\/td>\n<td>Tight GitHub integration, repo-scoped permissions<\/td>\n<td>Not Azure-native; different enterprise controls model<\/td>\n<td>You build\/deploy from GitHub and want registry near code<\/td>\n<\/tr>\n<tr>\n<td>Amazon ECR<\/td>\n<td>AWS workloads<\/td>\n<td>Deep AWS IAM integration, strong AWS ecosystem fit<\/td>\n<td>Cross-cloud complexity if you\u2019re on Azure<\/td>\n<td>Your workloads are primarily on AWS<\/td>\n<\/tr>\n<tr>\n<td>Google Artifact Registry<\/td>\n<td>GCP workloads<\/td>\n<td>Supports multiple artifact types, GCP integration<\/td>\n<td>Cross-cloud complexity if you\u2019re on Azure<\/td>\n<td>Your workloads are primarily on GCP<\/td>\n<\/tr>\n<tr>\n<td>Harbor (self-managed)<\/td>\n<td>Regulated or hybrid environments<\/td>\n<td>Full control, can run anywhere, rich policy features<\/td>\n<td>You operate and patch it; scaling\/HA is your job<\/td>\n<td>You need on-prem control or strict isolation<\/td>\n<\/tr>\n<tr>\n<td>JFrog Artifactory \/ Nexus<\/td>\n<td>Enterprises needing many artifact types<\/td>\n<td>Multi-format artifact management<\/td>\n<td>Licensing cost; operational complexity<\/td>\n<td>You want one platform for containers + many package types<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">15. Real-World Example<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Enterprise example: multi-region AKS platform with strict security<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> A global enterprise runs multiple AKS clusters across regions. They need private image distribution, audit trails, and consistent release promotion. They also need resilient pulls and controlled access across many teams.<\/li>\n<li><strong>Proposed architecture:<\/strong><\/li>\n<li>Azure Container Registry (Premium) in a primary region<\/li>\n<li>Geo-replication to secondary regions used by AKS clusters<\/li>\n<li>Private endpoints and restricted public access (where required)<\/li>\n<li>Entra ID groups mapped to Azure RBAC roles:<ul>\n<li>Platform pipeline identity: AcrPush<\/li>\n<li>Runtime identities: AcrPull<\/li>\n<\/ul>\n<\/li>\n<li>Diagnostic logs to Log Analytics + alerts<\/li>\n<li>Defender for Cloud plan for container registry scanning (licensed separately; verify exact capabilities)<\/li>\n<li><strong>Why ACR was chosen:<\/strong> Native AKS integration, Azure RBAC governance, and enterprise networking controls fit the organization\u2019s standards.<\/li>\n<li><strong>Expected outcomes:<\/strong><\/li>\n<li>Faster pulls across regions<\/li>\n<li>Reduced supply-chain exposure<\/li>\n<li>Clear audit logs for compliance<\/li>\n<li>Standardized release promotion using immutable digests<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Startup\/small-team example: simple CI to ACR for Container Apps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> A small team needs private images for a containerized API without managing infrastructure.<\/li>\n<li><strong>Proposed architecture:<\/strong><\/li>\n<li>One Azure Container Registry (Basic or Standard depending on needs)<\/li>\n<li>GitHub Actions builds and pushes images on merge to main<\/li>\n<li>Azure Container Apps pulls images for staging and production<\/li>\n<li>Simple cleanup job to remove old CI tags<\/li>\n<li><strong>Why ACR was chosen:<\/strong> Lowest operational overhead inside Azure; good fit for a small team already using Azure.<\/li>\n<li><strong>Expected outcomes:<\/strong><\/li>\n<li>Repeatable deployments from a trusted registry<\/li>\n<li>Minimal ops burden<\/li>\n<li>Clear path to Premium features if the product scales globally<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">16. FAQ<\/h2>\n\n\n\n<p>1) <strong>Is Azure Container Registry the same as Docker Hub?<\/strong><br\/>\nNo. Docker Hub is a public registry service. Azure Container Registry is a managed <strong>private registry in Azure<\/strong>, designed for enterprise identity, networking, and Azure integrations.<\/p>\n\n\n\n<p>2) <strong>What can I store in Azure Container Registry?<\/strong><br\/>\nPrimarily <strong>container images<\/strong> and <strong>OCI artifacts<\/strong> supported by ACR and your tools. For exact artifact support and recommended tooling, verify the current official docs: https:\/\/learn.microsoft.com\/azure\/container-registry\/<\/p>\n\n\n\n<p>3) <strong>Do I need AKS to use Azure Container Registry?<\/strong><br\/>\nNo. You can use ACR with many runtimes: AKS, Azure Container Apps, Azure Container Instances, App Service for Containers, or even non-Azure Kubernetes.<\/p>\n\n\n\n<p>4) <strong>How do I control who can pull images?<\/strong><br\/>\nUse Azure RBAC with roles like <strong>AcrPull<\/strong> assigned to users, groups, service principals, or managed identities at the registry scope (or narrower scopes where supported).<\/p>\n\n\n\n<p>5) <strong>Should I enable the admin user?<\/strong><br\/>\nFor production, typically <strong>no<\/strong>. Use Entra ID + Azure RBAC and managed identities. Admin user is convenient for labs or legacy tooling but increases risk.<\/p>\n\n\n\n<p>6) <strong>What\u2019s the difference between Basic, Standard, and Premium?<\/strong><br\/>\nThey differ in performance and available features (for example, geo-replication is Premium). Always compare using the official pricing and feature documentation.<\/p>\n\n\n\n<p>7) <strong>How do I reduce image pull latency for multi-region clusters?<\/strong><br\/>\nConsider <strong>geo-replication<\/strong> (Premium) or place registries closer to compute. Also use smaller images and stable layers.<\/p>\n\n\n\n<p>8) <strong>Can I restrict registry access to private networks only?<\/strong><br\/>\nACR supports private connectivity patterns (e.g., private endpoints), but availability and exact configuration can be SKU\/region dependent. Verify current docs and test DNS behavior.<\/p>\n\n\n\n<p>9) <strong>How do I delete old images safely?<\/strong><br\/>\nAdopt a tag strategy:\n&#8211; Keep release tags (and\/or pin by digest)\n&#8211; Remove ephemeral CI tags\n&#8211; Use retention policies if available in your SKU (verify)\nTest cleanup in non-prod first.<\/p>\n\n\n\n<p>10) <strong>Can ACR build images without Docker on my laptop?<\/strong><br\/>\nYes, via <strong>ACR Tasks<\/strong> (cloud builds). Verify current ACR Tasks features and billing in official docs.<\/p>\n\n\n\n<p>11) <strong>How do I integrate ACR with GitHub Actions?<\/strong><br\/>\nAuthenticate to Azure (OIDC recommended) and then <code>docker build<\/code> + <code>docker push<\/code> to the ACR login server. Microsoft has official GitHub Actions for Azure login\u2014verify current recommended workflow in GitHub\/Microsoft docs.<\/p>\n\n\n\n<p>12) <strong>Does ACR scan images for vulnerabilities by default?<\/strong><br\/>\nACR itself is a registry. Vulnerability scanning typically comes from <strong>Microsoft Defender for Cloud<\/strong> plans or third-party tools. Verify the current Defender capabilities and licensing.<\/p>\n\n\n\n<p>13) <strong>Is it okay to deploy using the <code>latest<\/code> tag?<\/strong><br\/>\nAvoid it in production. Use immutable version tags and\/or deploy by digest to ensure the exact artifact is deployed.<\/p>\n\n\n\n<p>14) <strong>How do I troubleshoot unauthorized pull errors in Kubernetes?<\/strong><br\/>\nCheck:\n&#8211; The identity used by nodes\/workloads\n&#8211; RBAC role assignments (AcrPull)\n&#8211; If using imagePullSecrets, confirm credentials\n&#8211; Network\/DNS if private endpoints are in use<\/p>\n\n\n\n<p>15) <strong>Can I mirror upstream images into ACR?<\/strong><br\/>\nYes, using import capabilities and\/or pipeline workflows. Ensure you respect upstream licensing and keep track of digests for reproducibility.<\/p>\n\n\n\n<p>16) <strong>What logs should I enable for auditing?<\/strong><br\/>\nEnable ACR diagnostic logs to Log Analytics for login\/auth events and repository events, then create alerts for anomalies.<\/p>\n\n\n\n<p>17) <strong>How do I estimate ACR cost?<\/strong><br\/>\nUse the official pricing page and calculator:\n&#8211; https:\/\/azure.microsoft.com\/pricing\/details\/container-registry\/\n&#8211; https:\/\/azure.microsoft.com\/pricing\/calculator\/<br\/>\nEstimate SKU + stored GB + pull\/push patterns + optional tasks and logs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">17. Top Online Resources to Learn Azure Container Registry<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Resource Type<\/th>\n<th>Name<\/th>\n<th>Why It Is Useful<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Official documentation<\/td>\n<td>Azure Container Registry documentation<\/td>\n<td>Canonical reference for features, auth, networking, tasks, and operations: https:\/\/learn.microsoft.com\/azure\/container-registry\/<\/td>\n<\/tr>\n<tr>\n<td>Official quickstart<\/td>\n<td>Quickstart: Create a private container registry using the Azure CLI<\/td>\n<td>Step-by-step creation and push\/pull patterns (official): https:\/\/learn.microsoft.com\/azure\/container-registry\/container-registry-get-started-azure-cli<\/td>\n<\/tr>\n<tr>\n<td>Official concepts<\/td>\n<td>About registries, repositories, and images<\/td>\n<td>Clarifies core concepts and terminology: https:\/\/learn.microsoft.com\/azure\/container-registry\/container-registry-concepts<\/td>\n<\/tr>\n<tr>\n<td>Official how-to<\/td>\n<td>ACR authentication options<\/td>\n<td>Explains Entra ID integration, service principals, and admin user: https:\/\/learn.microsoft.com\/azure\/container-registry\/container-registry-authentication<\/td>\n<\/tr>\n<tr>\n<td>Official how-to<\/td>\n<td>Azure Container Registry Tasks<\/td>\n<td>Cloud builds, triggers, and automation: https:\/\/learn.microsoft.com\/azure\/container-registry\/container-registry-tasks-overview<\/td>\n<\/tr>\n<tr>\n<td>Official how-to<\/td>\n<td>Geo-replication (Premium)<\/td>\n<td>Multi-region replication details and constraints: https:\/\/learn.microsoft.com\/azure\/container-registry\/container-registry-geo-replication<\/td>\n<\/tr>\n<tr>\n<td>Official how-to<\/td>\n<td>Private Link \/ private endpoints for ACR<\/td>\n<td>Secure networking patterns and DNS considerations (verify SKU requirements): https:\/\/learn.microsoft.com\/azure\/container-registry\/container-registry-private-link<\/td>\n<\/tr>\n<tr>\n<td>Official monitoring<\/td>\n<td>Monitor Azure Container Registry<\/td>\n<td>Metrics, logs, and diagnostic settings: https:\/\/learn.microsoft.com\/azure\/container-registry\/monitor-container-registry<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Container Registry pricing<\/td>\n<td>SKU and usage pricing details: https:\/\/azure.microsoft.com\/pricing\/details\/container-registry\/<\/td>\n<\/tr>\n<tr>\n<td>Pricing tool<\/td>\n<td>Azure Pricing Calculator<\/td>\n<td>Build scenario-based estimates: https:\/\/azure.microsoft.com\/pricing\/calculator\/<\/td>\n<\/tr>\n<tr>\n<td>Architecture guidance<\/td>\n<td>Azure Architecture Center (Containers)<\/td>\n<td>Broader container architecture patterns: https:\/\/learn.microsoft.com\/azure\/architecture\/guide\/architecture-styles\/microservices<\/td>\n<\/tr>\n<tr>\n<td>Official samples<\/td>\n<td>Azure Container Registry samples (GitHub search starting point)<\/td>\n<td>Practical scripts and examples (verify repository authenticity): https:\/\/github.com\/Azure-Samples<\/td>\n<\/tr>\n<tr>\n<td>Community learning<\/td>\n<td>Kubernetes image management best practices<\/td>\n<td>Helps with tagging\/digests, rollout patterns, and pull secrets; validate against your cluster\/runtime versions<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">18. Training and Certification Providers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Institute<\/th>\n<th>Suitable Audience<\/th>\n<th>Likely Learning Focus<\/th>\n<th>Mode<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps engineers, SREs, platform teams<\/td>\n<td>CI\/CD, containers, Kubernetes, Azure DevOps practices<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>ScmGalaxy.com<\/td>\n<td>Beginners to intermediate DevOps learners<\/td>\n<td>SCM, CI\/CD foundations, DevOps toolchains<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.scmgalaxy.com\/<\/td>\n<\/tr>\n<tr>\n<td>CLoudOpsNow.in<\/td>\n<td>Cloud engineers, operations teams<\/td>\n<td>Cloud operations, monitoring, reliability practices<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.cloudopsnow.in\/<\/td>\n<\/tr>\n<tr>\n<td>SreSchool.com<\/td>\n<td>SREs, operations engineers<\/td>\n<td>SRE principles, observability, incident response<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.sreschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>AiOpsSchool.com<\/td>\n<td>Ops and DevOps teams exploring AIOps<\/td>\n<td>Automation, AIOps concepts, operational analytics<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.aiopsschool.com\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">19. Top Trainers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Platform\/Site<\/th>\n<th>Likely Specialization<\/th>\n<th>Suitable Audience<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>RajeshKumar.xyz<\/td>\n<td>DevOps \/ cloud training content (verify offerings)<\/td>\n<td>Engineers seeking hands-on guidance<\/td>\n<td>https:\/\/rajeshkumar.xyz\/<\/td>\n<\/tr>\n<tr>\n<td>devopstrainer.in<\/td>\n<td>DevOps training and mentoring (verify offerings)<\/td>\n<td>Beginners to intermediate DevOps practitioners<\/td>\n<td>https:\/\/www.devopstrainer.in\/<\/td>\n<\/tr>\n<tr>\n<td>devopsfreelancer.com<\/td>\n<td>Freelance DevOps consulting\/training platform (verify offerings)<\/td>\n<td>Teams needing practical enablement<\/td>\n<td>https:\/\/www.devopsfreelancer.com\/<\/td>\n<\/tr>\n<tr>\n<td>devopssupport.in<\/td>\n<td>DevOps support and training resources (verify offerings)<\/td>\n<td>Ops\/DevOps teams needing troubleshooting help<\/td>\n<td>https:\/\/www.devopssupport.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">20. Top Consulting Companies<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Company Name<\/th>\n<th>Likely Service Area<\/th>\n<th>Where They May Help<\/th>\n<th>Consulting Use Case Examples<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>cotocus.com<\/td>\n<td>Cloud\/DevOps consulting (verify service catalog)<\/td>\n<td>Architecture, CI\/CD, container platforms<\/td>\n<td>ACR + AKS design, CI pipeline hardening, migration from self-hosted registry<\/td>\n<td>https:\/\/cotocus.com\/<\/td>\n<\/tr>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps consulting and enablement<\/td>\n<td>DevOps transformation, platform enablement<\/td>\n<td>ACR governance model, build\/push standards, multi-team onboarding<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>DEVOPSCONSULTING.IN<\/td>\n<td>DevOps consulting services (verify service catalog)<\/td>\n<td>Assessments, implementations, operations<\/td>\n<td>Secure ACR setup, private networking patterns, monitoring and cost optimization<\/td>\n<td>https:\/\/www.devopsconsulting.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">21. Career and Learning Roadmap<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn before Azure Container Registry<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Containers fundamentals<\/strong><\/li>\n<li>Dockerfile basics, image layers, registries, tags vs digests<\/li>\n<li><strong>Linux basics<\/strong><\/li>\n<li>Processes, ports, filesystems (helps with container debugging)<\/li>\n<li><strong>Azure fundamentals<\/strong><\/li>\n<li>Subscriptions, resource groups, IAM (Azure RBAC), networking basics<\/li>\n<li><strong>Git + CI\/CD basics<\/strong><\/li>\n<li>pipelines, secrets, artifacts, environments<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn after Azure Container Registry<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure Kubernetes Service (AKS)<\/strong><\/li>\n<li>attaching ACR, workload identity patterns, image pull strategies<\/li>\n<li><strong>Azure Container Apps<\/strong><\/li>\n<li>revisions, traffic splitting, managed identity pulls<\/li>\n<li><strong>Supply-chain security<\/strong><\/li>\n<li>vulnerability scanning, SBOM concepts, signing\/verification (verify current recommended tooling for ACR)<\/li>\n<li><strong>Observability<\/strong><\/li>\n<li>Azure Monitor, Log Analytics queries, alerting on registry and runtime signals<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Job roles that use it<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>DevOps Engineer<\/li>\n<li>Platform Engineer<\/li>\n<li>Site Reliability Engineer (SRE)<\/li>\n<li>Cloud Engineer<\/li>\n<li>Security Engineer (container security)<\/li>\n<li>Software Engineer (microservices)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Certification path (Azure)<\/h3>\n\n\n\n<p>ACR appears within broader Azure and Kubernetes learning paths rather than as a standalone certification topic. Relevant certification tracks often include:\n&#8211; <strong>AZ-104<\/strong> (Azure Administrator)\n&#8211; <strong>AZ-305<\/strong> (Azure Solutions Architect)\n&#8211; <strong>AZ-400<\/strong> (DevOps Engineer Expert)\n&#8211; Kubernetes-related certifications (CNCF) can complement Azure container platform skills<\/p>\n\n\n\n<p>Verify current certification details on Microsoft Learn: https:\/\/learn.microsoft.com\/credentials\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Project ideas for practice<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Build a CI pipeline that pushes images to ACR with semantic tags and git SHA tags.<\/li>\n<li>Deploy to AKS using digest pinning and validate rollbacks.<\/li>\n<li>Implement retention and cleanup automation (scripted cleanup + approvals).<\/li>\n<li>Enable diagnostic logs and build a Log Analytics dashboard for pull\/push and auth failures.<\/li>\n<li>Implement private endpoints and validate DNS + network paths from AKS node pools.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">22. Glossary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ACR:<\/strong> Azure Container Registry.<\/li>\n<li><strong>OCI:<\/strong> Open Container Initiative; defines standards for container image formats and distribution.<\/li>\n<li><strong>Repository:<\/strong> A named collection of related artifacts\/images inside a registry (e.g., <code>team\/service<\/code>).<\/li>\n<li><strong>Tag:<\/strong> A mutable label pointing to a specific image manifest (e.g., <code>v1.2.0<\/code>).<\/li>\n<li><strong>Digest:<\/strong> Immutable cryptographic identifier of an image manifest (e.g., <code>sha256:...<\/code>).<\/li>\n<li><strong>Manifest:<\/strong> Metadata describing an image and its layers.<\/li>\n<li><strong>Layer:<\/strong> A filesystem diff stored as a blob; images consist of multiple layers.<\/li>\n<li><strong>AcrPull\/AcrPush:<\/strong> Azure RBAC roles granting pull-only or push+pull permissions.<\/li>\n<li><strong>Managed identity:<\/strong> Azure identity for services to authenticate without stored secrets.<\/li>\n<li><strong>Private endpoint (Private Link):<\/strong> Private IP interface to an Azure PaaS service.<\/li>\n<li><strong>Geo-replication:<\/strong> Replicating registry content to other Azure regions (typically Premium).<\/li>\n<li><strong>Retention policy:<\/strong> Rules that automatically delete artifacts based on criteria (availability depends on SKU and feature support).<\/li>\n<li><strong>CI\/CD:<\/strong> Continuous Integration \/ Continuous Delivery or Deployment.<\/li>\n<li><strong>Image promotion:<\/strong> Process of moving an image through environments (dev \u2192 staging \u2192 prod), ideally by digest.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">23. Summary<\/h2>\n\n\n\n<p>Azure Container Registry is Azure\u2019s managed private registry for container images and OCI artifacts. It matters because it sits on the critical path between building software and running it\u2014so it needs strong identity, auditing, networking, and operational controls.<\/p>\n\n\n\n<p>In Azure container architectures, Azure Container Registry is typically the central artifact store feeding AKS, Container Apps, and other runtimes. Cost is primarily driven by SKU selection, stored image volume, data transfer, build automation usage (ACR Tasks), and observability\/log storage. Security hinges on Entra ID + Azure RBAC, least privilege (AcrPull\/AcrPush), avoiding admin credentials, and using private networking where required.<\/p>\n\n\n\n<p>Use Azure Container Registry when you want Azure-native container artifact management with enterprise controls and integrations. Next, deepen your skills by integrating ACR with AKS or Azure Container Apps, enabling monitoring\/diagnostics, and implementing a production-ready tag\/digest promotion strategy.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Containers<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40,27],"tags":[],"class_list":["post-406","post","type-post","status-publish","format-standard","hentry","category-azure","category-containers"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/406","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=406"}],"version-history":[{"count":0,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/406\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=406"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=406"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}