![]() |
VOOZH | about |
dotnet add package Azure.Containers.ContainerRegistry --version 1.3.0
NuGet\Install-Package Azure.Containers.ContainerRegistry -Version 1.3.0
<PackageReference Include="Azure.Containers.ContainerRegistry" Version="1.3.0" />
<PackageVersion Include="Azure.Containers.ContainerRegistry" Version="1.3.0" />Directory.Packages.props
<PackageReference Include="Azure.Containers.ContainerRegistry" />Project file
paket add Azure.Containers.ContainerRegistry --version 1.3.0
#r "nuget: Azure.Containers.ContainerRegistry, 1.3.0"
#:package Azure.Containers.ContainerRegistry@1.3.0
#addin nuget:?package=Azure.Containers.ContainerRegistry&version=1.3.0Install as a Cake Addin
#tool nuget:?package=Azure.Containers.ContainerRegistry&version=1.3.0Install as a Cake Tool
Azure Container Registry allows you to store and manage container images and artifacts in a private registry for all types of container deployments.
Use the client library for Azure Container Registry to:
Source code | Package (NuGet) | API reference documentation | REST API documentation | Product documentation
To develop .NET application code that can connect to an Azure Container Registry instance, you will need the Azure.Containers.ContainerRegistry library.
Install the Azure Container Registry client library for .NET with NuGet:
dotnet add package Azure.Containers.ContainerRegistry
You will need an Azure subscription and a Container Registry service instance for your application to connect to.
To create a new Container Registry, you can use the Azure Portal, Azure PowerShell, or the Azure CLI. Here'a an example of creating a new registry using the Azure CLI:
az acr create --name myregistry --resource-group myresourcegroup --location westus --sku Basic
For your application to connect to your registry, you'll need to create a ContainerRegistryClient that can authenticate with it. The Azure Identity library makes it easy to add Azure Active Directory support for authenticating Azure SDK clients with their corresponding Azure services.
When you're developing and debugging your application locally, you can use your own user to authenticate with your registry. One way to accomplish this is to authenticate your user with the Azure CLI and run your application from this environment. If your application is using a client that has been constructed to authenticate with DefaultAzureCredential, it will correctly authenticate with the registry at the specified endpoint.
// Create a ContainerRegistryClient that will authenticate to your registry through Azure Active Directory
Uri endpoint = new Uri("https://myregistry.azurecr.io");
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(),
new ContainerRegistryClientOptions()
{
Audience = ContainerRegistryAudience.AzureResourceManagerPublicCloud
});
Please see the Azure Identity README for more approaches to authenticating with DefaultAzureCredential, both locally and in deployment environments. To connect to registries in non-public Azure Clouds, see the samples below.
For more information on using AAD with Azure Container Registry, please see the service's Authentication Overview.
A registry stores Docker images and OCI Artifacts. An image or artifact consists of a manifest and layers. An image's manifest describes the layers that make up the image, and is uniquely identified by its digest. An image can also be "tagged" to give it a human-readable alias. An image or artifact can have zero or more tags associated with it, and each tag uniquely identifies the image. A collection of images that share the same name but have different tags, is referred to as a repository.
For more information please see Container Registry Concepts.
We guarantee that all client instance methods are thread-safe and independent of each other (guideline). This ensures that the recommendation to reuse client instances is always safe, even across threads.
Client options | Accessing the response | Long-running operations | Handling failures | Diagnostics | Mocking | Client lifetime
The following snippets show brief samples of common developer scenarios using the ACR SDK library.
Please note that each sample assumes there is a REGISTRY_ENDPOINT environment variable set to a string containing the https:// prefix and the name of the login server, for example "https://myregistry.azurecr.io".
This section contains ContainerRegistryClient samples.
Iterate through the collection of repositories in the registry.
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
// Get the collection of repository names from the registry
Pageable<string> repositories = client.GetRepositoryNames();
foreach (string repository in repositories)
{
Console.WriteLine(repository);
}
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient for anonymous access
ContainerRegistryClient client = new ContainerRegistryClient(endpoint);
// Obtain a RegistryArtifact object to get access to image operations
RegistryArtifact image = client.GetArtifact("library/hello-world", "latest");
// List the set of tags on the hello_world image tagged as "latest"
Pageable<ArtifactTagProperties> tags = image.GetAllTagProperties();
// Iterate through the image's tags, listing the tagged alias for the image
Console.WriteLine($"{image.FullyQualifiedReference} has the following aliases:");
foreach (ArtifactTagProperties tag in tags)
{
Console.WriteLine($" {image.RegistryEndpoint.Host}/{image.RepositoryName}:{tag}");
}
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient and RegistryArtifact to access image operations
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
RegistryArtifact image = client.GetArtifact("library/hello-world", "latest");
// Set permissions on the v1 image's "latest" tag
image.UpdateTagProperties("latest", new ArtifactTagProperties()
{
CanWrite = false,
CanDelete = false
});
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
// Iterate through repositories
Pageable<string> repositoryNames = client.GetRepositoryNames();
foreach (string repositoryName in repositoryNames)
{
ContainerRepository repository = client.GetRepository(repositoryName);
// Obtain the images ordered from newest to oldest
Pageable<ArtifactManifestProperties> imageManifests =
repository.GetAllManifestProperties(manifestOrder: ArtifactManifestOrder.LastUpdatedOnDescending);
// Delete images older than the first three.
foreach (ArtifactManifestProperties imageManifest in imageManifests.Skip(3))
{
RegistryArtifact image = repository.GetArtifact(imageManifest.Digest);
Console.WriteLine($"Deleting image with digest {imageManifest.Digest}.");
Console.WriteLine($" Deleting the following tags from the image: ");
foreach (var tagName in imageManifest.Tags)
{
Console.WriteLine($" {imageManifest.RepositoryName}:{tagName}");
image.DeleteTag(tagName);
}
image.Delete();
}
}
The asynchronous APIs are identical to their synchronous counterparts, but methods end with the standard .NET "Async" suffix and return a Task.
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
// Get the collection of repository names from the registry
AsyncPageable<string> repositories = client.GetRepositoryNamesAsync();
await foreach (string repository in repositories)
{
Console.WriteLine(repository);
}
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient for anonymous access
ContainerRegistryClient client = new ContainerRegistryClient(endpoint);
// Obtain a RegistryArtifact object to get access to image operations
RegistryArtifact image = client.GetArtifact("library/hello-world", "latest");
// List the set of tags on the hello_world image tagged as "latest"
AsyncPageable<ArtifactTagProperties> tags = image.GetAllTagPropertiesAsync();
// Iterate through the image's tags, listing the tagged alias for the image
Console.WriteLine($"{image.FullyQualifiedReference} has the following aliases:");
await foreach (ArtifactTagProperties tag in tags)
{
Console.WriteLine($" {image.RegistryEndpoint.Host}/{image.RepositoryName}:{tag}");
}
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient and RegistryArtifact to access image operations
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
RegistryArtifact image = client.GetArtifact("library/hello-world", "v1");
// Set permissions on the image's "latest" tag
await image.UpdateTagPropertiesAsync("latest", new ArtifactTagProperties()
{
CanWrite = false,
CanDelete = false
});
// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
// Iterate through repositories
AsyncPageable<string> repositoryNames = client.GetRepositoryNamesAsync();
await foreach (string repositoryName in repositoryNames)
{
ContainerRepository repository = client.GetRepository(repositoryName);
// Obtain the images ordered from newest to oldest
AsyncPageable<ArtifactManifestProperties> imageManifests =
repository.GetAllManifestPropertiesAsync(manifestOrder: ArtifactManifestOrder.LastUpdatedOnDescending);
// Delete images older than the first three.
await foreach (ArtifactManifestProperties imageManifest in imageManifests.Skip(3))
{
RegistryArtifact image = repository.GetArtifact(imageManifest.Digest);
Console.WriteLine($"Deleting image with digest {imageManifest.Digest}.");
Console.WriteLine($" Deleting the following tags from the image: ");
foreach (var tagName in imageManifest.Tags)
{
Console.WriteLine($" {imageManifest.RepositoryName}:{tagName}");
await image.DeleteTagAsync(tagName);
}
await image.DeleteAsync();
}
}
This section contains samples for ContainerRegistryContentClient that show how to upload and download images.
First, create a blob client.
// Get the service endpoint from the environment
Uri endpoint = new(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
string repository = "sample-oci-image";
string tag = "demo";
// Create a new ContainerRegistryContentClient
ContainerRegistryContentClient client = new(endpoint, repository, new DefaultAzureCredential());
To upload a full image, we need to upload individual layers and configuration. After that we can upload a manifest which describes an image or artifact and assign it a tag.
// Create a manifest to list files in this image
OciImageManifest manifest = new(schemaVersion: 2);
// Upload a config file
BinaryData config = BinaryData.FromString("Sample config");
UploadRegistryBlobResult uploadConfigResult = await client.UploadBlobAsync(config);
// Update manifest with config info
manifest.Configuration = new OciDescriptor()
{
Digest = uploadConfigResult.Digest,
SizeInBytes = uploadConfigResult.SizeInBytes,
MediaType = "application/vnd.oci.image.config.v1+json"
};
// Upload a layer file
BinaryData layer = BinaryData.FromString("Sample layer");
UploadRegistryBlobResult uploadLayerResult = await client.UploadBlobAsync(layer);
// Update manifest with layer info
manifest.Layers.Add(new OciDescriptor()
{
Digest = uploadLayerResult.Digest,
SizeInBytes = uploadLayerResult.SizeInBytes,
MediaType = "application/vnd.oci.image.layer.v1.tar"
});
// Finally, upload the manifest file
await client.SetManifestAsync(manifest, tag);
To download a full image, we need to download its manifest and then download individual layers and configuration.
// Download the manifest to obtain the list of files in the image
GetManifestResult result = await client.GetManifestAsync(tag);
OciImageManifest manifest = result.Manifest.ToObjectFromJson<OciImageManifest>();
string manifestFile = Path.Combine(path, "manifest.json");
using (FileStream stream = File.Create(manifestFile))
{
await result.Manifest.ToStream().CopyToAsync(stream);
}
// Download and write out the config
DownloadRegistryBlobResult configBlob = await client.DownloadBlobContentAsync(manifest.Configuration.Digest);
string configFile = Path.Combine(path, "config.json");
using (FileStream stream = File.Create(configFile))
{
await configBlob.Content.ToStream().CopyToAsync(stream);
}
// Download and write out the layers
foreach (OciDescriptor layerInfo in manifest.Layers)
{
string layerFile = Path.Combine(path, TrimSha(layerInfo.Digest));
using (FileStream stream = File.Create(layerFile))
{
await client.DownloadBlobToAsync(layerInfo.Digest, stream);
}
}
static string TrimSha(string digest)
{
int index = digest.IndexOf(':');
if (index > -1)
{
return digest.Substring(index + 1);
}
return digest;
}
GetManifestResult manifestResult = await client.GetManifestAsync(tag);
await client.DeleteManifestAsync(manifestResult.Digest);
GetManifestResult result = await client.GetManifestAsync(tag);
OciImageManifest manifest = result.Manifest.ToObjectFromJson<OciImageManifest>();
foreach (OciDescriptor layerInfo in manifest.Layers)
{
await client.DeleteBlobAsync(layerInfo.Digest);
}
To authenticate with a registry in a National Cloud, you will need to make the following additions to your client configuration:
AuthorityHost in the credential options or via the AZURE_AUTHORITY_HOST environment variableAudience in ContainerRegistryClientOptions// Create a ContainerRegistryClient that will authenticate through AAD in the China national cloud
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
ContainerRegistryClient client = new ContainerRegistryClient(endpoint,
new DefaultAzureCredential(
new DefaultAzureCredentialOptions()
{
AuthorityHost = AzureAuthorityHosts.AzureChina
}),
new ContainerRegistryClientOptions()
{
Audience = ContainerRegistryAudience.AzureChina
});
See our troubleshooting guide for details on how to diagnose various failure scenarios.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit cla.microsoft.com.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact with any additional questions or comments.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on Azure.Containers.ContainerRegistry:
| Package | Downloads |
|---|---|
|
Azure.Bicep.Core
Bicep compiler core functionality. The Bicep team has made this NuGet package publicly available on nuget.org. While it is public, it is not a supported package. Any dependency you take on this package will be done at your own risk and we reserve the right to push breaking changes to this package at any time. |
|
|
Azure.Bicep.Decompiler
Bicep compiler decompile functionality. The Bicep team has made this NuGet package publicly available on nuget.org. While it is public, it is not a supported package. Any dependency you take on this package will be done at your own risk and we reserve the right to push breaking changes to this package at any time. |
|
|
CasCap.Api.Azure.ContainerRegistry
Helper library for Azure Container Registry repository and manifest operations. |
|
|
CasCap.Apis.Azure.ContainerRegistry
Helper library for Azure Container Registry. |
|
|
Azure.Bicep.McpServer.Core
Bicep MCP Server Core SDK. Provides the AddBicepMcpServer() extension method and Bicep tool definitions for building custom MCP servers. |
Showing the top 5 popular GitHub repositories that depend on Azure.Containers.ContainerRegistry:
| Repository | Stars |
|---|---|
|
Azure/azure-powershell
Microsoft Azure PowerShell
|
|
|
microsoft/mcp
Catalog of official Microsoft MCP (Model Context Protocol) server implementations for AI-powered data access and tool integration
|
|
|
Azure/azure-mcp
The Azure MCP Server, bringing the power of Azure to your agents.
|
|
|
dotnet/docker-tools
This is a repo to house some common tools for our various docker repos.
|
|
|
microsoft/CromwellOnAzure
Microsoft Genomics implementation of the Broad Institute's Cromwell workflow engine on Azure
|
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.0 | 351,541 | 1/6/2026 |
| 1.2.0 | 1,323,365 | 2/10/2025 |
| 1.2.0-beta.1 | 22,271 | 7/12/2023 |
| 1.1.1 | 1,230,987 | 12/13/2023 |
| 1.1.0 | 1,015,007 | 5/11/2023 |
| 1.1.0-beta.9 | 79,266 | 4/11/2023 |
| 1.1.0-beta.8 | 35,846 | 3/14/2023 |
| 1.1.0-beta.7 | 366 | 3/7/2023 |
| 1.1.0-beta.6 | 8,960 | 2/7/2023 |
| 1.1.0-beta.5 | 6,019 | 1/11/2023 |
| 1.1.0-beta.4 | 223,883 | 4/6/2022 |
| 1.1.0-beta.3 | 60,488 | 11/10/2021 |
| 1.1.0-beta.2 | 4,139 | 10/25/2021 |
| 1.1.0-beta.1 | 5,831 | 9/7/2021 |
| 1.0.0 | 224,929 | 1/14/2022 |
| 1.0.0-beta.5 | 4,158 | 11/18/2021 |
| 1.0.0-beta.4 | 679 | 8/10/2021 |
| 1.0.0-beta.3 | 1,277 | 6/8/2021 |
| 1.0.0-beta.2 | 1,286 | 5/11/2021 |
| 1.0.0-beta.1 | 2,126 | 4/8/2021 |