Conteneuriser une application .NET avec dotnet publish
Les conteneurs ont de nombreuses fonctionnalités et divers avantages : une infrastructure immuable qui fournit une architecture portable et permet la scalabilité. L’image vous permettra de créer des conteneurs pour votre environnement de développement local, votre cloud privé ou votre cloud public. Dans ce tutoriel, vous allez apprendre à conteneuriser une application .NET à l’aide de la commande dotnet publish.
Prérequis
Installez les éléments requis suivants :
- SDK .NET 8+
Si .NET est installé, utilisez la commandedotnet --info
pour identifier le Kit SDK que vous utilisez. - Docker Community Edition
- SDK .NET 7+
Si .NET est installé, utilisez la commandedotnet --info
pour identifier le Kit SDK que vous utilisez. - Docker Community Edition
En plus de ces prérequis, il est recommandé de vous familiariser avec les Services Worker dans .NET.
Créer une application .NET
Vous avez besoin d’une application .NET à conteneuriser. Commencez donc par créer une application à partir d’un modèle. Ouvrez votre terminal, créez un dossier de travail (sample-directory) si vous ne l’avez pas déjà fait et modifiez les répertoires afin de vous y trouver. Dans le dossier de travail, exécutez la commande suivante pour créer un projet dans un sous-répertoire nommé Worker :
dotnet new worker -o Worker -n DotNet.ContainerImage
Votre arborescence de dossiers doit ressembler à ce qui suit :
📁 sample-directory
└──📂 Worker
├──appsettings.Development.json
├──appsettings.json
├──DotNet.ContainerImage.csproj
├──Program.cs
├──Worker.cs
└──📂 obj
├── DotNet.ContainerImage.csproj.nuget.dgspec.json
├── DotNet.ContainerImage.csproj.nuget.g.props
├── DotNet.ContainerImage.csproj.nuget.g.targets
├── project.assets.json
└── project.nuget.cache
La commande dotnet new
crée un dossier nommé Worker et génère un service Worker qui, lors de l’exécution, enregistre un message toutes les secondes. À partir de votre session de terminal, modifiez les répertoires et accédez au dossier Worker. Utilisez la commande dotnet run
pour démarrer l’application.
dotnet run
Building...
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:00 -05:00
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: .\Worker
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:01 -05:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:02 -05:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:03 -05:00
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
Attempting to cancel the build...
Le modèle Worker effectue une boucle indéfiniment. Utilisez la commande Annuler Ctrl+C pour l’arrêter.
Ajouter un package NuGet
Le package NuGet Microsoft.NET.Build.Containers est actuellement nécessaire pour publier un projet non-web en tant que conteneur. Pour ajouter le package NuGet Microsoft.NET.Build.Containers
au modèle Worker, exécutez la commande dotnet add package suivante :
dotnet add package Microsoft.NET.Build.Containers
Conseil
Si vous créez une application web et que vous utilisez le kit de développement logiciel (SDK) .NET 7.0.300 ou une version supérieure à celle du package n’est pas obligatoire, le kit de développement logiciel (SDK) dispose des mêmes fonctionnalités prêtes à l’emploi.
Définir le nom de l’image conteneur
Différentes options de configuration sont disponibles lors de la publication d’une application en tant que conteneur.
Par défaut, le nom de l’image conteneur est le AssemblyName
du projet. Si ce nom n’est pas valide comme nom d’image conteneur, vous pouvez le remplacer en spécifiant un ContainerRepository
, comme indiqué dans le fichier projet suivant :
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
<ContainerRepository>dotnet-worker-image</ContainerRepository>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>
</Project>
Pour plus d’informations, consultez ContainerRepository.
Par défaut, le nom de l’image conteneur est le AssemblyName
du projet. Si ce nom n’est pas valide comme nom d’image conteneur, vous pouvez le remplacer en spécifiant un ContainerImageName
(obsolète) ou le ContainerRepository
préféré, comme indiqué dans le fichier projet suivant :
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
<ContainerImageName>dotnet-worker-image</ContainerImageName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.NET.Build.Containers" Version="7.0.401" />
</ItemGroup>
</Project>
Pour plus d’informations, consultez ContainerImageName.
Publier une application .NET
Pour publier l’application .NET en tant que conteneur, utilisez la commande dotnet publish suivante :
dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
La commande CLI .NET précédente publie l’application en tant que conteneur :
- Ciblage de Linux en tant que système d’exploitation (
--os linux
). - Spécification d’une architecture x64 (
--arch x64
). - Utilisation de la configuration de mise en production (
-c Release
).
Important
Pour générer le conteneur localement, vous devez avoir le démon Docker en cours d’exécution. S’il n’est pas en cours d’exécution lorsque vous tentez de publier l’application en tant que conteneur, vous rencontrerez une erreur similaire à ce qui suit :
..\build\Microsoft.NET.Build.Containers.targets(66,9): error MSB4018:
The "CreateNewImage" task failed unexpectedly. [..\Worker\DotNet.ContainerImage.csproj]
Conseil
Selon le type d’application que vous conteneurisez, les commutateurs de ligne de commande (options) peuvent varier. Par exemple, l’argument /t:PublishContainer
n’est requis que pour les applications .NET non web, comme les modèles console
et worker
. Pour les modèles web, remplacez l’argument /t:PublishContainer
par -p:PublishProfile=DefaultContainer
. Pour plus d’informations, consultez Builds de conteneur du SDK .NET, problème n° 141.
La commande génère des sorties qui ressemblent à l’exemple suivant :
Determining projects to restore...
All projects are up-to-date for restore.
DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\DotNet.ContainerImage.dll
DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\publish\
Building image 'dotnet-worker-image' with tags latest on top of base image mcr.microsoft.com/dotnet/aspnet:8.0
Pushed container 'dotnet-worker-image:latest' to Docker daemon
Determining projects to restore...
All projects are up-to-date for restore.
DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\DotNet.ContainerImage.dll
DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\publish\
Building image 'dotnet-worker-image' with tags 1.0.0 on top of base image mcr.microsoft.com/dotnet/aspnet:7.0
Pushed container 'dotnet-worker-image:1.0.0' to Docker daemon
Cette commande compile votre application Worker dans le dossier publish et envoie le conteneur à votre registre Docker local.
Configurer l’image conteneur
Vous pouvez contrôler de nombreux aspects du conteneur généré via les propriétés MSBuild. En général, si vous pouvez utiliser une commande dans un Dockerfile pour définir une configuration, vous pouvez en faire de même via MSBuild.
Remarque
Les seules exceptions à ce problème sont les commandes RUN
. En raison de la façon dont les conteneurs sont générés, vous ne pouvez pas les émuler. Si vous avez besoin de cette fonctionnalité, vous devez utiliser un Dockerfile pour générer vos images conteneur.
ContainerArchiveOutputPath
À compter de .NET 8, vous pouvez créer un conteneur directement en tant qu’archive tar.gz. Cette fonctionnalité est utile si votre workflow n’est pas simple et vous oblige, par exemple, à exécuter un outil d’analyse sur vos images avant de les envoyer (push). Une fois l’archive créée, vous pouvez la déplacer, l’analyser ou la charger dans une chaîne d’outils Docker locale.
Pour publier dans une archive, ajoutez la propriété ContainerArchiveOutputPath
à votre commande dotnet publish
, par exemple :
dotnet publish \
-p PublishProfile=DefaultContainer \
-p ContainerArchiveOutputPath=./images/sdk-container-demo.tar.gz
Vous pouvez spécifier un nom de dossier ou un chemin d’accès avec un nom de fichier spécifique. Si vous spécifiez le nom du dossier, le nom de fichier généré pour le fichier d’archive d’images sera $(ContainerRepository).tar.gz
. Ces archives peuvent contenir plusieurs étiquettes à l’intérieur, car un seul fichier est créé pour toutes les ContainerImageTags
.
Configuration du nommage des images conteneur
Les images conteneur suivent une convention de nommage spécifique. Le nom de l’image est composé de plusieurs parties : registre, port facultatif, référentiel et étiquette et famille facultatives.
REGISTRY[:PORT]/REPOSITORY[:TAG[-FAMILY]]
Par exemple, prenez le nom complet de l’image mcr.microsoft.com/dotnet/runtime:8.0-alpine
:
mcr.microsoft.com
est le registre (qui représente ici le registre de conteneurs Microsoft).dotnet/runtime
est le référentiel (mais certains considèrent cela leuser/repository
).8.0-alpine
est l’étiquette et la famille (la famille est un spécificateur facultatif qui permet de lever l’ambiguïté de l’empaquetage du système d’exploitation).
Certaines propriétés décrites dans les sections suivantes correspondent à la gestion des parties du nom de l’image généré. Regardez le tableau suivant qui établit la relation entre le nom de l’image et les propriétés de build :
Partie du nom de l’image | Propriété MSBuild | Exemples de valeurs |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerRepository |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
FAMILY |
ContainerFamily |
-alpine |
Partie du nom de l’image | Propriété MSBuild | Exemples de valeurs |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerImageName |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
Les sections suivantes décrivent les différentes propriétés qui peuvent être utilisées pour contrôler l’image conteneur générée.
ContainerBaseImage
La propriété d’image de base de conteneur contrôle l’image utilisée comme base de votre image. Par défaut, les valeurs suivantes sont déduites en fonction des propriétés de votre projet :
- Si votre projet est autonome, l’image
mcr.microsoft.com/dotnet/runtime-deps
est utilisée comme image de base. - Si votre projet est un projet ASP.NET Core, l’image
mcr.microsoft.com/dotnet/aspnet
est utilisée comme image de base. - Sinon, l’image
mcr.microsoft.com/dotnet/runtime
est utilisée comme image de base.
L’étiquette de l’image est déduite comme étant le composant numérique du TargetFramework
de votre choix. Par exemple, un projet ciblant net6.0
entraîne l’étiquette 6.0
de l’image de base déduite, et un projet net7.0-linux
utilisera l’étiquette 7.0
, etc.
Si vous définissez une valeur ici, vous devez définir le nom complet de l’image à utiliser comme base, y compris toute étiquette de votre choix :
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:8.0</ContainerBaseImage>
</PropertyGroup>
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:7.0</ContainerBaseImage>
</PropertyGroup>
ContainerFamily
À partir de .NET 8, vous pouvez utiliser la propriété MSBuild ContainerFamily
pour choisir une autre famille d’images conteneur fournies par Microsoft comme image de base pour votre application. Une fois définie, cette valeur est ajoutée à la fin de l’étiquette spécifique au TFM sélectionnée, en modifiant l’étiquette fournie. Par exemple, pour utiliser les variantes Alpine Linux des images de base .NET, vous pouvez définir ContainerFamily
sur alpine
:
<PropertyGroup>
<ContainerFamily>alpine</ContainerFamily>
</PropertyGroup>
La configuration du projet précédent entraîne une étiquette finale 8.0-alpine
pour une application cible .NET 8.
Ce champ est libre et peut souvent être utilisé pour sélectionner différentes distributions de système d’exploitation, configurations de package par défaut ou toute autre saveur des modifications apportées à une image de base. Ce champ est ignoré quand ContainerBaseImage
est défini. Pour plus d’informations, consultez Images conteneur .NET.
ContainerRuntimeIdentifier
La propriété d’identificateur du runtime de conteneur contrôle le système d’exploitation et l’architecture utilisés par votre conteneur si votre ContainerBaseImage prend en charge plusieurs plateformes. Par exemple, l’image mcr.microsoft.com/dotnet/runtime
prend actuellement en charge les images linux-x64
, linux-arm
, linux-arm64
et win10-x64
toutes derrière la même balise. Par conséquent, les outils ont besoin d’un moyen de savoir quelle version de ces versions vous envisagez d’utiliser. Par défaut, ce paramètre est défini sur la valeur du RuntimeIdentifier
que vous avez choisi lors de la publication du conteneur. Cette propriété a rarement besoin d’être définie explicitement. Utilisez plutôt l’option -r
de la dotnet publish
commande. Si l’image que vous avez choisie ne prend pas en charge le RuntimeIdentifier
que vous avez choisi, vous obtenez une erreur qui décrit les RuntimeIdentifiers pris en charge par l’image.
Vous pouvez toujours définir la propriété ContainerBaseImage
sur un nom d’image complet, y compris la balise, pour éviter d’avoir à utiliser cette propriété.
<PropertyGroup>
<ContainerRuntimeIdentifier>linux-arm64</ContainerRuntimeIdentifier>
</PropertyGroup>
Pour plus d’informations sur les identificateurs d’exécution pris en charge par .NET, consultez le catalogue RID.
ContainerRegistry
La propriété de registre de conteneurs contrôle le registre de destination, l’emplacement vers lequel l’image nouvellement créée sera envoyée. Par défaut, elle est envoyée (push) au démon Docker local, mais vous pouvez également spécifier un registre distant. Lorsque vous utilisez un registre distant qui nécessite une authentification, vous vous authentifiez à l’aide des mécanismes connus docker login
. Pour plus d’informations, consultez Authentification auprès des registres de conteneurs. Pour obtenir un exemple concret d’utilisation de cette propriété, considérez l’exemple XML suivant :
<PropertyGroup>
<ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
</PropertyGroup>
Cet outil prend en charge la publication sur n’importe quel registre qui prend en charge l’API Docker Registry HTTP V2. Cela inclut explicitement les registres suivants (et probablement beaucoup plus implicitement) :
- Azure Container Registry
- Amazon Elastic Container Registry
- Google Artifact Registry
- Docker Hub
- GitHub Packages
- Container Registry hébergé par GitLab
- Quay.io
Pour obtenir des notes sur l’utilisation de ces registres, consultez les notes spécifiques au registre.
ContainerRepository
Le référentiel de conteneur est le nom de l’image elle-même, par exemple dotnet/runtime
ou my-app
. Par défaut, le AssemblyName
du projet est utilisé.
<PropertyGroup>
<ContainerRepository>my-app</ContainerRepository>
</PropertyGroup>
ContainerImageName
Le nom de l’image conteneur contrôle le nom de l’image elle-même, par exemple dotnet/runtime
ou my-app
. Par défaut, le AssemblyName
du projet est utilisé.
<PropertyGroup>
<ContainerImageName>my-app</ContainerImageName>
</PropertyGroup>
Remarque
À compter de .NET 8, ContainerImageName
est déconseillé en faveur de ContainerRepository
.
Les noms d’image se composent d’un ou plusieurs segments délimités par des barres obliques, chacun pouvant contenir uniquement des caractères alphanumériques minuscules, des points, des traits de soulignement et des tirets, et doit commencer par une lettre ou un nombre. Tous les autres caractères entraînent la levée d’une erreur.
ContainerImageTag(s)
La propriété d’étiquette d’image conteneur contrôle les étiquettes générées pour l’image. Pour spécifier une seule utilisation d’étiquette ContainerImageTag
et pour plusieurs étiquettes, utilisez ContainerImageTags
.
Important
Lorsque vous utilisez ContainerImageTags
, vous obtenez plusieurs images, une par étiquette unique.
Les étiquettes sont souvent utilisées pour faire référence à différentes versions d’une application, mais elles peuvent également faire référence à différentes distributions de système d’exploitation, voire à différentes configurations.
À partir de .NET 8, lorsqu’une étiquette n’est pas fournie, la valeur par défaut est latest
.
Par défaut, le Version
du projet est utilisé comme valeur d’étiquette.
Pour remplacer la valeur par défaut, spécifiez l’une des options suivantes :
<PropertyGroup>
<ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>
Pour spécifier plusieurs étiquettes, utilisez un ensemble d’étiquettes délimitées par des points-virgules dans la propriété ContainerImageTags
, comme lorsque vous définissez plusieurs TargetFrameworks
:
<PropertyGroup>
<ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
</PropertyGroup>
Les étiquettes peuvent contenir jusqu’à 127 caractères alphanumériques, points, traits de soulignement et tirets. Elles doivent commencer par un caractère alphanumérique ou un trait de soulignement. Toute autre forme entraîne la levée d’une erreur.
Remarque
Lors de l’utilisation de ContainerImageTags
, les étiquettes sont délimitées par un caractère ;
. Si vous appelez dotnet publish
à partir de la ligne de commande (comme c’est le cas avec la plupart des environnements CI/CD), vous devez inclure les valeurs dans un wrapper unique '
et interne avec des quotes doubles "
, par exemple (='"tag-1;tag-2"'
). Prenons le commande dotnet publish
suivante :
dotnet publish -p ContainerImageTags='"1.2.3-alpha2;latest"'
Cela entraîne la génération de deux images : my-app:1.2.3-alpha2
et my-app:latest
.
Conseil
Si vous rencontrez des problèmes avec la propriété ContainerImageTags
, envisagez de définir une variable d’environnement ContainerImageTags
à la place :
ContainerImageTags='1.2.3;latest' dotnet publish
ContainerLabel
L’étiquette du conteneur ajoute une étiquette de métadonnées au conteneur. Les étiquettes n’ont aucun impact sur le conteneur au moment de l’exécution, mais elles sont souvent utilisées pour stocker les métadonnées de version et de création à utiliser par les analyseurs de sécurité et d’autres outils d’infrastructure. Vous pouvez spécifier n’importe quel nombre d’étiquettes de conteneur.
Le nœud ContainerLabel
a deux attributs :
Include
: clé de l’étiquette.Value
: valeur de l’étiquette (elle peut être vide).
<ItemGroup>
<ContainerLabel Include="org.contoso.businessunit" Value="contoso-university" />
</ItemGroup>
Pour obtenir la liste des étiquettes créées par défaut, consultez Étiquettes de conteneur par défaut.
Configurer l’exécution du conteneur
Pour contrôler l’exécution du conteneur, vous pouvez utiliser les propriétés MSBuild suivantes.
ContainerWorkingDirectory
Le nœud du répertoire de travail du conteneur contrôle le répertoire de travail du conteneur, le répertoire dans lequel les commandes sont exécutées si aucune autre commande n’est exécutée.
Par défaut, la valeur du répertoire /app
est utilisée comme répertoire de travail.
<PropertyGroup>
<ContainerWorkingDirectory>/bin</ContainerWorkingDirectory>
</PropertyGroup>
ContainerPort
Le port de conteneur ajoute des ports TCP ou UDP à la liste des ports connus pour le conteneur. Cela permet aux runtimes de conteneur comme Docker de mapper automatiquement ces ports à la machine hôte. Il est souvent utilisé comme documentation pour le conteneur, mais peut également être utilisé pour activer le mappage automatique des ports.
Le nœud ContainerPort
a deux attributs :
Include
: numéro de port à exposer.Type
: la valeur par défaut esttcp
; les valeurs valides sonttcp
ouudp
.
<ItemGroup>
<ContainerPort Include="80" Type="tcp" />
</ItemGroup>
À partir de .NET 8, ContainerPort
est déduite lorsqu’elle n’est pas fournie explicitement en fonction de plusieurs variables d’environnement ASP.NET connues :
ASPNETCORE_URLS
ASPNETCORE_HTTP_PORTS
ASPNETCORE_HTTPS_PORTS
Si ces variables d’environnement sont présentes, leurs valeurs sont analysées et converties en mappages de ports TCP. Ces variables d’environnement sont lues à partir de votre image de base, le cas échéant, ou à partir des variables d’environnement définies dans votre projet via les éléments ContainerEnvironmentVariable
. Pour plus d’informations, consultez ContainerEnvironmentVariable.
ContainerEnvironmentVariable
Le nœud de variable d’environnement de conteneur vous permet d’ajouter des variables d’environnement au conteneur. Les variables d’environnement sont accessibles immédiatement à l’application en cours d’exécution dans le conteneur et sont souvent utilisées pour modifier le comportement d’exécution de l’application en cours d’exécution.
Le nœud ContainerEnvironmentVariable
a deux attributs :
Include
: Nom de la variable d’environnement.Value
: Valeur de la variable d’environnement.
<ItemGroup>
<ContainerEnvironmentVariable Include="LOGGER_VERBOSITY" Value="Trace" />
</ItemGroup>
Pour plus d’informations, consultez Variables d’environnement .NET.
Configurer des commandes de conteneur
Par défaut, les outils de conteneur lancent votre application à l’aide du fichier binaire AppHost généré pour votre application (si votre application utilise un AppHost) ou de la commande dotnet
plus la DLL de votre application.
Toutefois, vous pouvez contrôler la façon dont votre application est exécutée à l’aide d’une combinaison de ContainerAppCommand
, ContainerAppCommandArgs
, ContainerDefaultArgs
et ContainerAppCommandInstruction
.
Ces différents points de configuration existent car différentes images de base utilisent différentes combinaisons du conteneur ENTRYPOINT
et des propriétés COMMAND
, et vous souhaitez pouvoir les prendre en charge. Les valeurs par défaut doivent être utilisables pour la plupart des applications, mais si vous souhaitez personnaliser le comportement de lancement de votre application, vous devez :
- Identifier le fichier binaire à exécuter et le définir comme
ContainerAppCommand
- Identifier les arguments requis pour que votre application s’exécute et les définir comme
ContainerAppCommandArgs
- Identifier les arguments facultatifs (le cas échéant) et qui peuvent être remplacés par un utilisateur et les définir comme
ContainerDefaultArgs
- Paramétrez
ContainerAppCommandInstruction
surDefaultArgs
Pour plus d’informations, consultez les éléments de configuration suivants.
ContainerAppCommand
L’élément de configuration de la commande d’application est le point d’entrée logique de votre application. Pour la plupart des applications, il s’agit d’AppHost, le fichier binaire exécutable généré pour votre application. Si votre application ne génère pas d’AppHost, cette commande est généralement dotnet <your project dll>
. Ces valeurs sont appliquées après n’importe quel ENTRYPOINT
dans votre conteneur de base, ou directement si aucun ENTRYPOINT
n’est défini.
La configuration ContainerAppCommand
a une propriété Include
unique, qui représente la commande, l’option ou l’argument à utiliser dans la commande entrypoint :
<ItemGroup Label="ContainerAppCommand Assignment">
<!-- This is how you would start the dotnet ef tool in your container -->
<ContainerAppCommand Include="dotnet" />
<ContainerAppCommand Include="ef" />
<!-- This shorthand syntax means the same thing, note the semicolon separating the tokens. -->
<ContainerAppCommand Include="dotnet;ef" />
</ItemGroup>
ContainerAppCommandArgs
Cet élément de configuration d’arguments de commande d’application représente tous les arguments logiquement requis pour votre application qui doivent être appliqués à ContainerAppCommand
. Par défaut, aucun n’est généré pour une application. Lorsqu’il sont présents, les arguments sont appliqués à votre conteneur lorsqu’il est exécuté.
La configuration ContainerAppCommandArgs
a une propriété unique Include
, qui représente l’option ou l’argument à appliquer à la commande ContainerAppCommand
.
<ItemGroup>
<!-- Assuming the ContainerAppCommand defined above,
this would be the way to force the database to update.
-->
<ContainerAppCommandArgs Include="database" />
<ContainerAppCommandArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerAppCommandArgs Include="database;update" />
</ItemGroup>
ContainerDefaultArgs
Cet élément de configuration d’arguments par défaut représente tous les arguments remplçables par l’utilisateur pour votre application. Il s’agit d’un bon moyen de fournir des valeurs par défaut que votre application peut avoir besoin d’exécuter de manière à faciliter le démarrage, mais toujours facile à personnaliser.
La configuration ContainerDefaultArgs
a une propriété unique Include
, qui représente l’option ou l’argument à appliquer à la commande ContainerAppCommand
.
<ItemGroup>
<!-- Assuming the ContainerAppCommand defined above,
this would be the way to force the database to update.
-->
<ContainerDefaultArgs Include="database" />
<ContainerDefaultArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerDefaultArgs Include="database;update" />
</ItemGroup>
ContainerAppCommandInstruction
La configuration des instructions de commande d’application permet de contrôler la façon dont ContainerEntrypoint
, ContainerEntrypointArgs
, ContainerAppCommand
, ContainerAppCommandArgs
, et ContainerDefaultArgs
sont combinés pour former la commande finale exécutée dans le conteneur. Cela dépend considérablement de si un ENTRYPOINT
est présent dans l’image de base. Cette propriété peut prendre une des trois valeurs : "DefaultArgs"
, "Entrypoint"
, ou "None"
.
Entrypoint
:- Dans ce mode, le point d’entrée est défini par
ContainerAppCommand
,ContainerAppCommandArgs
, etContainerDefaultArgs
.
- Dans ce mode, le point d’entrée est défini par
None
:- Dans ce mode, le point d’entrée est défini par
ContainerEntrypoint
,ContainerEntrypointArgs
, etContainerDefaultArgs
.
- Dans ce mode, le point d’entrée est défini par
DefaultArgs
:- Il s’agit du mode le plus complexe. Si aucun des éléments
ContainerEntrypoint[Args]
n’est présent,ContainerAppCommand[Args]
etContainerDefaultArgs
sont utilisés pour créer le point d’entrée et la commande. Le point d’entrée de l’image de base pour les images de base qui ont été codées en dur versdotnet
ou/usr/bin/dotnet
est ignoré afin que vous disposiez d’un contrôle total. - Si
ContainerEntrypoint
etContainerAppCommand
sont présents, alorsContainerEntrypoint
devient le point d’entrée etContainerAppCommand
devient la commande.
- Il s’agit du mode le plus complexe. Si aucun des éléments
Remarque
Les éléments de configuration ContainerEntrypoint
et ContainerEntrypointArgs
sont déconseillés à partir de .NET 8.
Important
Ceci est destiné aux utilisateurs avancés, la plupart des applications n’ont pas besoin de personnaliser leur point d’entrée à ce point. Pour plus d’informations et si vous souhaitez fournir des cas d’usage pour vos scénarios, consultez GitHub : discussions sur les builds du conteneur du Kit de développement logiciel (SDK) .NET.
ContainerUser
La propriété de configuration utilisateur contrôle l’utilisateur par défaut sur lequel le conteneur s’exécute. Il est souvent utilisé pour exécuter le conteneur en tant qu’utilisateur non-racine, ce qui est une bonne pratique pour la sécurité. Il existe quelques contraintes à connaître pour cette configuration :
- Elle peut prendre différentes formes : nom d’utilisateur, identifiant utilisateur Linux, nom du groupe, identifiant de groupe Linux,
username:groupname
, et autres variantes d’identifiant. - Il n’y a pas de vérification de l’existence de l’utilisateur ou du groupe spécifié sur l’image.
- La modification de l’utilisateur peut modifier le comportement de l’application, en particulier en ce qui concerne les éléments tels que les autorisations du Système de fichiers.
La valeur par défaut de ce champ varie selon le TFM du projet et le système d’exploitation cible :
- Si vous ciblez .NET 8 ou une version ultérieure et que vous utilisez les images de runtime Microsoft, alors :
- sur Linux, l’utilisateur sans racine
app
est utilisé (bien qu’il soit référencé par son identifiant utilisateur) - sur Windows, l’utilisateur sans racine
ContainerUser
est utilisé
- sur Linux, l’utilisateur sans racine
- Sinon, aucun
ContainerUser
par défaut n’est utilisé
<PropertyGroup>
<ContainerUser>my-existing-app-user</ContainerUser>
</PropertyGroup>
Conseil
La variable d’environnement APP_UID
est utilisée pour définir les informations utilisateur dans votre conteneur. Cette valeur peut provenir de variables d’environnement définies dans votre image de base (comme les images Microsoft .NET) ou vous pouvez la définir vous-même via la syntaxe ContainerEnvironmentVariable
.
Toutefois, vous pouvez contrôler la façon dont votre application est exécutée à l’aide de ContainerEntrypoint
et ContainerEntrypointArgs
.
ContainerEntrypoint
Le point d’entrée du conteneur peut être utilisé pour personnaliser le ENTRYPOINT
du conteneur, qui est l’exécutable appelé au démarrage du conteneur. Par défaut, pour les builds qui créent un hôte d’application, il est défini comme ContainerEntrypoint
. Pour les builds qui ne créent pas d’exécutable, le dotnet path/to/app.dll
est utilisé comme ContainerEntrypoint
.
Le nœud ContainerEntrypoint
a un attribut unique :
Include
: commande, option ou argument à utiliser dans la commandeContainerEntrypoint
.
Par exemple, considérez l’exemple suivant de groupe d’éléments de projet .NET :
<ItemGroup Label="Entrypoint Assignment">
<!-- This is how you would start the dotnet ef tool in your container -->
<ContainerEntrypoint Include="dotnet" />
<ContainerEntrypoint Include="ef" />
<!-- This shorthand syntax means the same thing.
Note the semicolon separating the tokens. -->
<ContainerEntrypoint Include="dotnet;ef" />
</ItemGroup>
ContainerEntrypointArgs
Le nœud args du point d’entrée du conteneur contrôle les arguments par défaut fournis au ContainerEntrypoint
. Il doit être utilisé lorsque le ContainerEntrypoint
est un programme que l’utilisateur peut vouloir utiliser seul. Par défaut, aucun ContainerEntrypointArgs
n’est créé en votre nom.
Le nœud ContainerEntrypointArg
a un attribut unique :
Include
: option ou argument à appliquer à la commandeContainerEntrypoint
.
Considérez l’exemple suivant de groupe d’éléments de projet .NET :
<ItemGroup>
<!-- Assuming the ContainerEntrypoint defined above,
this would be the way to update the database by
default, but let the user run a different EF command. -->
<ContainerEntrypointArgs Include="database" />
<ContainerEntrypointArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerEntrypointArgs Include="database;update" />
</ItemGroup>
Étiquettes de conteneur par défaut
Les étiquettes sont souvent utilisées pour fournir des métadonnées cohérentes sur les images conteneur. Ce package fournit certaines étiquettes par défaut pour favoriser une meilleure maintenance des images générées.
org.opencontainers.image.created
est défini sur le format ISO 8601 duDateTime
UTC actuel.
Pour plus d’informations, consultez Implémenter des étiquettes conventionnelles sur une infrastructure d’étiquettes existante.
Nettoyer les ressources
Dans cet article, vous avez publié un Worker .NET en tant qu’image conteneur. Si vous le souhaitez, supprimez cette ressource. Utilisez la commande docker images
pour afficher la liste des images installées.
docker images
Considérez l’exemple de sortie suivant :
REPOSITORY TAG IMAGE ID CREATED SIZE
dotnet-worker-image 1.0.0 25aeb97a2e21 12 seconds ago 191MB
Conseil
Les fichiers image peuvent être volumineux. En règle générale, vous supprimez les conteneurs temporaires que vous avez créés lors des tests et du développement de votre app. Vous conservez normalement les images de base avec le runtime installé si vous envisagez de créer d’autres images basées sur ce runtime.
Pour supprimer l’image, copiez l’ID d’image et exécutez la commande docker image rm
:
docker image rm 25aeb97a2e21
Étapes suivantes
- Annonce de la prise en charge des conteneurs intégrés pour le SDK .NET
- Tutoriel : Conteneuriser une application .NET
- Images conteneur .NET
- Passez en revue les services Azure qui prennent en charge des conteneurs
- En savoir plus sur les commandes Dockerfile
- Explorez les outils de conteneur dans Visual Studio