Skip to content

Commit e29a17c

Browse files
author
Cam Soper
authored
Add information about multi-RID container publishing in 8.0.405, 9.0.102, and 9.0.2xx to SDK Containerization reference (#45894)
* Add information about multi-RID container publishing in 8.0.405, 9.0.102, and 9.0.2xx to SDK Containerization reference Fixes #44440 * Tweaks * Additional note * lint * Add note on ContainerRuntimeIdentifiers subset requirement for multi-RID container publishing
1 parent a649518 commit e29a17c

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

docs/core/containers/publish-configuration.md

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
title: Containerize a .NET app reference
33
description: Reference material for containerizing a .NET app and configuring the container image.
44
ms.topic: reference
5-
ms.date: 01/27/2025
5+
ms.date: 04/22/2025
66
---
77

88
# Containerize a .NET app reference
99

10-
In this reference article, you learn how to configure the container image that's generated when you publish a .NET app as a container. This article covers the various properties that you can set to control the image, the execution environment, and the commands that are run when the container starts.
10+
In this reference article, you learn how to configure the container image generated when you publish a .NET app as a container. This article covers the various properties that you can set to control the image, the execution environment, and the commands that are run when the container starts.
1111

1212
## Configure container image
1313

1414
You can control many aspects of the generated container through MSBuild properties. In general, if you can use a command in a _Dockerfile_ to set some configuration, you can do the same via MSBuild.
1515

1616
> [!NOTE]
17-
> The only exceptions to this are `RUN` commands. Due to the way containers are built, those can't be emulated. If you need this functionality, you might consider using a _Dockerfile_ to build your container images.
17+
> The only exceptions to this are `RUN` commands. Due to the way containers are built, those commands can't be emulated. If you need this functionality, consider using a _Dockerfile_ to build your container images.
1818
1919
There's no way of performing `RUN` commands with the .NET SDK. These commands are often used to install some OS packages or create a new OS user, or any number of arbitrary things. If you would like to keep using the .NET SDK container building feature, you can instead create a custom base image with these changes and then using this base image. For more information, see [`ContainerBaseImage`](#containerbaseimage).
2020

@@ -118,11 +118,16 @@ To specify multiple container runtime identifiers for multi-architecture images,
118118
</PropertyGroup>
119119
```
120120

121+
> [!IMPORTANT]
122+
> The `ContainerRuntimeIdentifiers` property must be a subset of the `RuntimeIdentifiers` property. If this condition isn't met, critical parts of the build pipeline may fail.
123+
>
124+
> Setting multiple `ContainerRuntimeIdentifiers` results in a multi-architecture image being created. For more information, see [Multi-architecture images](#multi-architecture-images).
125+
121126
For more information regarding the runtime identifiers supported by .NET, see [RID catalog](../rid-catalog.md).
122127

123128
### `ContainerRegistry`
124129

125-
The container registry property controls the destination registry, the place that the newly created image will be pushed to. By default it's pushed to the local Docker daemon, but you can also specify a remote registry. When using a remote registry that requires authentication, you authenticate using the well-known `docker login` mechanisms. For more information, See [authenticating to container registries](https://aka.ms/dotnet/containers/auth) for more details. For a concrete example of using this property, consider the following XML example:
130+
The container registry property controls the destination registry, the place that the newly created image is to be pushed to. By default it's pushed to the local Docker daemon, but you can also specify a remote registry. When using a remote registry that requires authentication, you authenticate using the well-known `docker login` mechanisms. For more information, See [authenticating to container registries](https://aka.ms/dotnet/containers/auth) for more details. For a concrete example of using this property, consider the following XML example:
126131

127132
```xml
128133
<PropertyGroup>
@@ -159,13 +164,13 @@ Image names consist of one or more slash-delimited segments, each of which can o
159164
The container image tag property controls the tags that are generated for the image. To specify a single tag use `ContainerImageTag` and for multiple tags use `ContainerImageTags`.
160165

161166
> [!IMPORTANT]
162-
> When you use `ContainerImageTags`, you'll end up with multiple images, one per unique tag.
167+
> When you use `ContainerImageTags`, you end up with multiple images, one per unique tag.
163168
164169
Tags are often used to refer to different versions of an app, but they can also refer to different operating system distributions, or even different configurations.
165170

166171
Starting with .NET 8, when a tag isn't provided the default is `latest`.
167172

168-
To override the default, specify either of the following:
173+
To override the default, specify either of the following properties:
169174

170175
```xml
171176
<PropertyGroup>
@@ -184,7 +189,7 @@ To specify multiple tags, use a semicolon-delimited set of tags in the `Containe
184189
Tags can only contain up to 127 alphanumeric characters, periods, underscores, and dashes. They must start with an alphanumeric character or an underscore. Any other form results in an error being thrown.
185190

186191
> [!NOTE]
187-
> When using `ContainerImageTags` or any MSBuild property that needs to configure `;` delimited values. If you're calling `dotnet publish` from the command line (as is the case with most CI/CD environments), you need to understand the limitations of the environment's inability to disambiguate delimiters and quotations, thus requiring proper escaping. This differs between PowerShell and Bash. Consider the following `dotnet publish` commands in their respective environments:
192+
> When using `ContainerImageTags` or any MSBuild property requiring `;`-delimited values, ensure proper escaping when calling `dotnet publish` from the command line, especially in CI/CD environments. Escaping rules differ between PowerShell and Bash. For example:
188193
>
189194
> ```powershell
190195
> dotnet publish --os linux --arch x64 /t:PublishContainer /p:ContainerImageTags=`"1.2.3-alpha2`;latest`"
@@ -310,7 +315,7 @@ These different configuration points exist because different base images use dif
310315

311316
- Identify the binary to run and set it as `ContainerAppCommand`
312317
- Identify which arguments are _required_ for your application to run and set them as `ContainerAppCommandArgs`
313-
- Identify which arguments (if any) are _optional_ and could be overridden by a user and set them as `ContainerDefaultArgs`
318+
- Identify which arguments (if any) are _optional_ and are able to be overridden by a user and set them as `ContainerDefaultArgs`
314319
- Set `ContainerAppCommandInstruction` to `DefaultArgs`
315320

316321
For more information, see the following configuration items.
@@ -334,7 +339,7 @@ The `ContainerAppCommand` configuration has a single `Include` property, which r
334339

335340
### `ContainerAppCommandArgs`
336341

337-
This app command args configuration item represents any logically required arguments for your app that should be applied to the `ContainerAppCommand`. By default, none are generated for an app. When present, the args are applied to your container when it's run.
342+
This app command args configuration item represents any logically required arguments for your app that should be applied to the `ContainerAppCommand`. By default, none are generated for an app. When present, the args are applied to your container when it runs.
338343

339344
The `ContainerAppCommandArgs` configuration has a single `Include` property, which represents the option or argument to apply to the `ContainerAppCommand` command.
340345

@@ -444,10 +449,26 @@ Where possible, existing MSBuild properties provide the values for these labels.
444449
| `org.opencontainers.image.licenses` | | `ContainerLicenseExpression` | `PackageLicenseExpression` | `ContainerGenerateLabelsImageLicenses` | |
445450
| `org.opencontainers.image.title` | | `ContainerTitle` | `Title` | `ContainerGenerateLabelsImageTitle` | |
446451
| `org.opencontainers.image.base.name` | | `ContainerBaseImage` | | `ContainerGenerateLabelsImageBaseName` | |
447-
| `org.opencontainers.image.base.digest` | | | | `ContainerGenerateLabelsImageBaseDigest` | This will be the SHA digest of the chosen base image. Available from .NET SDK 9.0.100 onwards. |
452+
| `org.opencontainers.image.base.digest` | | | | `ContainerGenerateLabelsImageBaseDigest` | This is the SHA digest of the chosen base image. Available from .NET SDK 9.0.100 onwards. |
448453
| `org.opencontainers.image.source` | | `PrivateRepositoryUrl` | | `ContainerGenerateLabelsImageSource` | Only written if `PublishRepositoryUrl` is `true`. Also relies on Sourcelink infrastructure being part of the build. |
449454
| `org.opencontainers.image.revision` | | `SourceRevisionId` | | `ContainerGenerateLabelsImageRevision` | Only written if `PublishRepositoryUrl` is `true`. Also relies on Sourcelink infrastructure being part of the build. |
450455

456+
## Multi-architecture images
457+
458+
Multi-architecture images enable a single container image to support multiple architectures, simplifying cross-platform development and deployment. The .NET SDK supports this through the `ContainerRuntimeIdentifiers` property.
459+
460+
Beginning with SDK versions 8.0.405, 9.0.102, and 9.0.2xx, multi-RID container publishing is supported. When publishing with `/t:PublishContainer`:
461+
462+
- If a single `RuntimeIdentifier` or `ContainerRuntimeIdentifier` is specified, a single-architecture container is generated as before.
463+
- If no single `RuntimeIdentifier` is specified but multiple `RuntimeIdentifiers` or `ContainerRuntimeIdentifiers` are set, the SDK publishes the app for each specified RID and combines the resulting images into an [OCI Image Index](https://specs.opencontainers.org/image-spec/image-index/). This index allows multiple architecture-specific images to share a single name.
464+
465+
> [!NOTE]
466+
> The `ContainerRuntimeIdentifiers` property must be a subset of the `RuntimeIdentifiers` property. For more information, see [ContainerRuntimeIdentifiers](#containerruntimeidentifiers).
467+
468+
This feature streamlines container workflows in mixed-architecture environments. For example, a developer on a `linux-x64` host can publish a container supporting both `linux-x64` and `linux-arm64`, enabling deployment to either architecture without changing image names or labels.
469+
470+
The generated OCI Image Index is widely supported with modern container tooling, enhancing compatibility and ease of use.
471+
451472
## See also
452473

453474
- [Containerize a .NET app with dotnet publish](sdk-publish.md)

0 commit comments

Comments
 (0)