Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
320 changes: 317 additions & 3 deletions src/content/docs/azure/services/container-registry.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,324 @@
---
title: "Container Registry"
description: API coverage for Microsoft.ContainerRegistry in LocalStack for Azure.
title: 'Container Registry'
description: Get started with Azure Container Registry on LocalStack
template: doc
---

import AzureFeatureCoverage from "../../../../components/feature-coverage/AzureFeatureCoverage";
import AzureFeatureCoverage from '../../../../components/feature-coverage/AzureFeatureCoverage';

## Introduction

Azure Container Registry (ACR) is a managed, private OCI-compatible registry for storing and managing container images and Helm charts.
It integrates natively with Azure Kubernetes Service, Azure Container Instances, and Azure App Service to streamline container-based application deployments.
ACR is commonly used to build, store, and manage container images as part of a continuous integration and deployment pipeline. For more information, see [Azure Container Registry documentation](https://learn.microsoft.com/en-us/azure/container-registry/).

LocalStack for Azure provides a local environment for building and testing applications that make use of Azure Container Registry.
The supported APIs are available on our [API Coverage section](#api-coverage), which provides information on the extent of Container Registry's integration with LocalStack.

## Getting started

This guide walks you through creating a registry, logging in with Docker, pushing an image, and listing repositories. It assumes basic knowledge of the Azure CLI and our `azlocal` wrapper script.

Launch LocalStack using your preferred method. For more information, see [Introduction to LocalStack for Azure](/azure/getting-started/). Once the container is running, enable Azure CLI interception by running:

```bash
azlocal start-interception
```

This command points the `az` CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API.
To revert this configuration, run:

```bash
azlocal stop-interception
```

This reconfigures the `az` CLI to send commands to the official Azure management REST API.

### Create a resource group

Create a resource group to contain your Container Registry resources:

```bash
az group create \
--name rg-acr-demo \
--location westeurope
```

```bash title="Output"
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-acr-demo",
"location": "westeurope",
"name": "rg-acr-demo",
"properties": {
"provisioningState": "Succeeded"
},
...
}
```

### Create a container registry

Create a Basic-tier Azure Container Registry:

```bash
az acr create \
--name acrdoc89 \
--resource-group rg-acr-demo \
--location westeurope \
--sku Basic \
--admin-enabled true
```

```bash title="Output"
{
"adminUserEnabled": true,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-acr-demo/providers/Microsoft.ContainerRegistry/registries/acrdoc89",
"location": "westeurope",
"name": "acrdoc89",
"loginServer": "acrdoc89.azurecr.azure.localhost.localstack.cloud:4566",
"provisioningState": "Succeeded",
"sku": {
"name": "Basic",
"tier": "Basic"
},
...
}
```

### Log in with Docker

Authenticate the local Docker daemon to the registry using the Azure CLI:

```bash
az acr login --name acrdoc89
```

The emulator does not issue an AAD challenge, so the CLI prints an informational warning before confirming `Login Succeeded`. This is expected behaviour.

### Build and push an image

Create a minimal `Dockerfile` for the demo image:

```bash
cat > Dockerfile <<'EOF'
FROM alpine:latest
CMD ["echo", "Hello from LocalStack ACR!"]
EOF
```

Capture the registry login server returned by the emulator, then build and push the image using that address:

```bash
LOGIN_SERVER=$(az acr show --name acrdoc89 --resource-group rg-acr-demo --query loginServer -o tsv)
docker build -t $LOGIN_SERVER/hello:v1 .
docker push $LOGIN_SERVER/hello:v1
```

Alternatively build directly within the emulated registry:

```bash
az acr build \
--image hello:v1 \
--registry acrdoc89 \
.
```

### Pull an image

Pull the image back from the registry to confirm it was pushed correctly:

```bash
docker pull $LOGIN_SERVER/hello:v1
```

### Show and list registries

Get details for one registry and list all registries in the resource group:

```bash
az acr show \
--name acrdoc89 \
--resource-group rg-acr-demo

az acr list \
--resource-group rg-acr-demo
```

`az acr show` returns a single registry object; `az acr list` returns an array. Example fragments:

```bash title="Output (az acr show)"
{
"name": "acrdoc89",
"loginServer": "acrdoc89.azurecr.azure.localhost.localstack.cloud:4566",
"adminUserEnabled": true,
"provisioningState": "Succeeded",
...
}
```

```bash title="Output (az acr list)"
[
{
"name": "acrdoc89",
"loginServer": "acrdoc89.azurecr.azure.localhost.localstack.cloud:4566",
"provisioningState": "Succeeded",
...
}
]
```

### List image repositories

List repositories (image names) in the registry—for example, after you push an image in [Build and push an image](#build-and-push-an-image), the repository name (without a tag) appears here:

```bash
az acr repository list \
--name acrdoc89 \
--output table
```

```text title="Output"
Name
---------------
hello
```

### Check name availability

Registry names are globally unique in Azure. The following example shows the result when the name is already in use (for example, after you have created the registry):

```bash
az acr check-name --name acrdoc89
```

```bash title="Output"
{
"message": "The registry acrdoc89 is already in use.",
"nameAvailable": false,
"reason": "AlreadyExists"
}
```

### Update registry settings

Turn off the registry admin user (for example, to rely on other auth modes in your workflow):

```bash
az acr update --name acrdoc89 --resource-group rg-acr-demo --admin-enabled false
```

```bash title="Output"
{
"adminUserEnabled": false,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-acr-demo/providers/Microsoft.ContainerRegistry/registries/acrdoc89",
"loginServer": "acrdoc89.azurecr.azure.localhost.localstack.cloud:4566",
"name": "acrdoc89",
"provisioningState": "Succeeded",
"resourceGroup": "rg-acr-demo",
"sku": { "name": "Basic", "tier": "Basic" },
"type": "Microsoft.ContainerRegistry/registries"
...
}
```

## Show registry usage

Show current storage usage statistics for the registry:

```bash
az acr show-usage --name acrdoc89 --resource-group rg-acr-demo
```

```bash title="Output"
{
"value": [
{ "currentValue": 0, "limit": 10737418240, "name": "Size", "unit": "Bytes" },
{ "currentValue": 0, "limit": 2, "name": "Webhooks", "unit": "Count" },
{ "currentValue": 0, "limit": 100, "name": "ScopeMaps", "unit": "Count" },
{ "currentValue": 0, "limit": 100, "name": "Tokens", "unit": "Count" }
]
}
```

## Enable admin user and view credentials

Re-enable the admin user on the registry (for example, after you disabled it in [Update registry settings](#update-registry-settings)), so you can retrieve admin credentials:

```bash
az acr update \
--name acrdoc89 \
--resource-group rg-acr-demo \
--admin-enabled true
```

```bash title="Output"
{
"name": "acrdoc89",
"adminUserEnabled": true,
"provisioningState": "Succeeded",
...
}
```

Show admin credentials:

```bash
az acr credential show \
--name acrdoc89 \
--resource-group rg-acr-demo
```

```bash title="Output"
{
"username": "acrdoc89",
"passwords": [
{
"name": "password",
"value": "..."
},
{
"name": "password2",
"value": "..."
}
]
}
```

## Delete and verify

Delete the registry and remove the demo `Dockerfile` created earlier:

```bash
az acr delete --name acrdoc89 --resource-group rg-acr-demo --yes
rm -f Dockerfile
```

## Features

- **Full CRUD lifecycle:** Create, read, update, and delete registry resources using the Azure CLI or ARM API.
- **Admin user management:** Enable or disable admin user access and retrieve admin credentials.
- **Name availability check:** Validate registry name uniqueness via `az acr check-name`.
- **Image push and pull:** Push and pull OCI-compliant container images using the standard Docker CLI.
- **In-registry builds:** Build images directly in the emulated registry using `az acr build`.
- **Repository listing:** List repositories and image tags stored in the registry.
- **Registry usage reporting:** Retrieve storage and limit usage via `az acr show-usage`.
- **Registry update:** Modify registry properties such as admin enabled and SKU.
- **Multiple SKUs accepted:** Basic, Standard, and Premium SKU names are accepted (all backed by the same local registry).

## Limitations

- **Geo-replication not supported:** Multi-region registry replication is not emulated.
- **ACR Tasks beyond basic build:** Task scheduling, triggers, and multi-step task workflows are mocked at the ARM level but not executed.
- **Private endpoints for ACR:** Private Link–based network isolation is not supported.
- **Webhook notifications:** Registry webhooks defined via the ARM API are stored but not fired on push events.
- **Content trust and quarantine:** Image signing and quarantine policies are not enforced.
- **Delete is not persisted:** `az acr delete` returns HTTP 200 and exits cleanly, but the registry record is not removed from the in-memory store in the current emulator version.

## Samples

The following sample demonstrates how to use Azure Container Registry with LocalStack for Azure:

- [Azure Container Instances, Key Vault, and Storage](https://github.com/localstack/localstack-azure-samples/blob/main/samples/aci-blob-storage/python/README.md)

## API Coverage

Expand Down