You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
Copy file name to clipboardExpand all lines: docs/core/containers/publish-configuration.md
+31-10Lines changed: 31 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,19 +2,19 @@
2
2
title: Containerize a .NET app reference
3
3
description: Reference material for containerizing a .NET app and configuring the container image.
4
4
ms.topic: reference
5
-
ms.date: 01/27/2025
5
+
ms.date: 04/22/2025
6
6
---
7
7
8
8
# Containerize a .NET app reference
9
9
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.
11
11
12
12
## Configure container image
13
13
14
14
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.
15
15
16
16
> [!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.
18
18
19
19
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).
20
20
@@ -118,11 +118,16 @@ To specify multiple container runtime identifiers for multi-architecture images,
118
118
</PropertyGroup>
119
119
```
120
120
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
+
121
126
For more information regarding the runtime identifiers supported by .NET, see [RID catalog](../rid-catalog.md).
122
127
123
128
### `ContainerRegistry`
124
129
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:
126
131
127
132
```xml
128
133
<PropertyGroup>
@@ -159,13 +164,13 @@ Image names consist of one or more slash-delimited segments, each of which can o
159
164
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`.
160
165
161
166
> [!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.
163
168
164
169
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.
165
170
166
171
Starting with .NET 8, when a tag isn't provided the default is `latest`.
167
172
168
-
To override the default, specify either of the following:
173
+
To override the default, specify either of the following properties:
169
174
170
175
```xml
171
176
<PropertyGroup>
@@ -184,7 +189,7 @@ To specify multiple tags, use a semicolon-delimited set of tags in the `Containe
184
189
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.
185
190
186
191
> [!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:
188
193
>
189
194
> ```powershell
190
195
> 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
310
315
311
316
- Identify the binary to run and set it as `ContainerAppCommand`
312
317
- 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`
314
319
- Set `ContainerAppCommandInstruction` to `DefaultArgs`
315
320
316
321
For more information, see the following configuration items.
@@ -334,7 +339,7 @@ The `ContainerAppCommand` configuration has a single `Include` property, which r
334
339
335
340
### `ContainerAppCommandArgs`
336
341
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.
338
343
339
344
The `ContainerAppCommandArgs` configuration has a single `Include` property, which represents the option or argument to apply to the `ContainerAppCommand` command.
340
345
@@ -444,10 +449,26 @@ Where possible, existing MSBuild properties provide the values for these labels.
|`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. |
448
453
|`org.opencontainers.image.source`||`PrivateRepositoryUrl`||`ContainerGenerateLabelsImageSource`| Only written if `PublishRepositoryUrl` is `true`. Also relies on Sourcelink infrastructure being part of the build. |
449
454
|`org.opencontainers.image.revision`||`SourceRevisionId`||`ContainerGenerateLabelsImageRevision`| Only written if `PublishRepositoryUrl` is `true`. Also relies on Sourcelink infrastructure being part of the build. |
450
455
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
+
451
472
## See also
452
473
453
474
-[Containerize a .NET app with dotnet publish](sdk-publish.md)
0 commit comments