Contentorizar uma aplicação .NET com dotnet publish
Os contêineres têm muitos recursos e benefícios, como ser uma infraestrutura imutável, fornecer uma arquitetura portátil e permitir escalabilidade. A imagem pode ser usada para criar contêineres para seu ambiente de desenvolvimento local, nuvem privada ou nuvem pública. Neste tutorial, você aprenderá como colocar em contêineres um aplicativo .NET usando o comando dotnet publishing .
Pré-requisitos
Instale os seguintes pré-requisitos:
- SDK do .NET 8+
Se você tiver o .NET instalado, use odotnet --info
comando para determinar qual SDK você está usando. - Docker Community Edition
- SDK do .NET 7+
Se você tiver o .NET instalado, use odotnet --info
comando para determinar qual SDK você está usando. - Docker Community Edition
Além desses pré-requisitos, é recomendável que você esteja familiarizado com os Serviços do Trabalhador no .NET.
Criar aplicação .NET
Você precisa de um aplicativo .NET para criar contêineres, então comece criando um novo aplicativo a partir de um modelo. Abra o terminal, crie uma pasta de trabalho (diretório de exemplo), se ainda não o fez, e altere os diretórios para que você esteja nele. Na pasta de trabalho, execute o seguinte comando para criar um novo projeto em um subdiretório chamado Worker:
dotnet new worker -o Worker -n DotNet.ContainerImage
Sua árvore de pastas tem a seguinte aparência:
📁 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
O dotnet new
comando cria uma nova pasta chamada Worker e gera um serviço de trabalho que, quando executado, registra uma mensagem a cada segundo. Na sessão do terminal, altere os diretórios e navegue até a pasta Trabalhador . Use o comando para iniciar o dotnet run
aplicativo.
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...
O modelo de trabalho é executado indefinidamente. Use o comando cancelar Ctrl+C para pará-lo.
Adicionar pacote NuGet
O pacote NuGet Microsoft.NET.Build.Containers é atualmente necessário para publicar projetos não Web como um contêiner. Para adicionar o pacote NuGet ao modelo de trabalho, execute o Microsoft.NET.Build.Containers
seguinte comando dotnet add package :
dotnet add package Microsoft.NET.Build.Containers
Gorjeta
Se você estiver criando um aplicativo Web e usando o .NET SDK 7.0.300 ou posterior, o pacote não será necessário — o SDK contém a mesma funcionalidade pronta para uso.
Definir o nome da imagem do contêiner
Há várias opções de configuração disponíveis ao publicar um aplicativo como um contêiner.
Por padrão, o nome da imagem do contêiner é o AssemblyName
do projeto. Se esse nome for inválido como um nome de imagem de contêiner, você poderá substituí-lo especificando um ContainerRepository
conforme mostrado no seguinte arquivo de projeto:
<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>
Para obter mais informações, consulte ContainerRepository.
Por padrão, o nome da imagem do contêiner é o AssemblyName
do projeto. Se esse nome for inválido como um nome de imagem de contêiner, você poderá substituí-lo especificando um (ContainerImageName
obsoleto) ou o preferido ContainerRepository
, conforme mostrado no seguinte arquivo de projeto:
<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>
Para obter mais informações, consulte ContainerImageName.
Publicar aplicativo .NET
Para publicar o aplicativo .NET como um contêiner, use o seguinte comando dotnet publishing :
dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
O comando anterior da CLI do .NET publica o aplicativo como um contêiner:
- Visando o Linux como o sistema operacional (
--os linux
). - Especificando uma arquitetura x64 (
--arch x64
). - Usando a configuração de liberação (
-c Release
).
Importante
Para criar o contêiner localmente, você deve ter o daemon do Docker em execução. Se ele não estiver em execução quando você tentar publicar o aplicativo como um contêiner, ocorrerá um erro semelhante ao seguinte:
..\build\Microsoft.NET.Build.Containers.targets(66,9): error MSB4018:
The "CreateNewImage" task failed unexpectedly. [..\Worker\DotNet.ContainerImage.csproj]
Gorjeta
Dependendo do tipo de aplicativo que você está fazendo contêineres, as opções de linha de comando (opções) podem variar. Por exemplo, o /t:PublishContainer
argumento só é necessário para aplicativos .NET não Web, como console
modelos e modelos worker
. Para modelos da Web, substitua o /t:PublishContainer
argumento por -p:PublishProfile=DefaultContainer
. Para obter mais informações, consulte Compilações de contêiner do SDK do .NET, edição #141.
O comando produz uma saída semelhante à saída de exemplo:
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
Este comando compila seu aplicativo de trabalho para a pasta de publicação e envia o contêiner para o registro do docker local.
Configurar imagem de contêiner
Você pode controlar muitos aspetos do contêiner gerado por meio das propriedades do MSBuild. Em geral, se você pode usar um comando em um Dockerfile para definir alguma configuração, você pode fazer o mesmo via MSBuild.
Nota
As únicas exceções são RUN
os comandos. Devido à forma como os contêineres são construídos, eles não podem ser emulados. Se precisar dessa funcionalidade, você precisará usar um Dockerfile para criar suas imagens de contêiner.
ContainerArchiveOutputPath
A partir do .NET 8, você pode criar um contêiner diretamente como um arquivo tar.gz . Esse recurso é útil se o fluxo de trabalho não for simples e exigir que você, por exemplo, execute uma ferramenta de digitalização sobre suas imagens antes de enviá-las. Depois que o arquivo é criado, você pode movê-lo, digitalizá-lo ou carregá-lo em uma cadeia de ferramentas local do Docker.
Para publicar em um arquivo, adicione a ContainerArchiveOutputPath
propriedade ao comando dotnet publish
, por exemplo:
dotnet publish \
-p PublishProfile=DefaultContainer \
-p ContainerArchiveOutputPath=./images/sdk-container-demo.tar.gz
Você pode especificar um nome de pasta ou um caminho com um nome de arquivo específico. Se você especificar o nome da pasta, o nome do arquivo gerado para o arquivo de imagem será $(ContainerRepository).tar.gz
. Esses arquivos podem conter várias tags dentro deles, apenas como um único arquivo é criado para todos ContainerImageTags
.
Configuração de nomenclatura de imagem de contêiner
As imagens de contêiner seguem uma convenção de nomenclatura específica. O nome da imagem é composto por várias partes, o registro, porta opcional, repositório e tag opcional e família.
REGISTRY[:PORT]/REPOSITORY[:TAG[-FAMILY]]
Por exemplo, considere o nome da imagem totalmente qualificada mcr.microsoft.com/dotnet/runtime:8.0-alpine
:
mcr.microsoft.com
é o registro (e, neste caso, representa o registro de contêiner da Microsoft).dotnet/runtime
é o repositório (mas alguns consideram isso ouser/repository
).8.0-alpine
é a tag e a família (a família é um especificador opcional que ajuda a desambiguar o empacotamento do sistema operacional).
Algumas propriedades descritas nas seções a seguir correspondem ao gerenciamento de partes do nome da imagem gerada. Considere a tabela a seguir que mapeia a relação entre o nome da imagem e as propriedades de compilação:
Parte do nome da imagem | Propriedade MSBuild | Valores de exemplo |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerRepository |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
FAMILY |
ContainerFamily |
-alpine |
Parte do nome da imagem | Propriedade MSBuild | Valores de exemplo |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerImageName |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
As seções a seguir descrevem as várias propriedades que podem ser usadas para controlar a imagem de contêiner gerada.
ContainerBaseImage
A propriedade container base image controla a imagem usada como base para sua imagem. Por padrão, os seguintes valores são inferidos com base nas propriedades do seu projeto:
- Se o seu projeto for independente, a
mcr.microsoft.com/dotnet/runtime-deps
imagem será usada como imagem base. - Se o seu projeto for um projeto ASP.NET Core, a
mcr.microsoft.com/dotnet/aspnet
imagem será usada como imagem base. - Caso contrário, a
mcr.microsoft.com/dotnet/runtime
imagem é usada como a imagem base.
A tag da imagem é inferida como sendo o componente numérico do seu escolhido TargetFramework
. Por exemplo, um projeto direcionado net6.0
resulta na 6.0
tag da imagem base inferida, e um net7.0-linux
projeto usa a 7.0
tag e assim por diante.
Se você definir um valor aqui, deverá definir o nome totalmente qualificado da imagem para usar como base, incluindo qualquer tag de sua preferência:
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:8.0</ContainerBaseImage>
</PropertyGroup>
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:7.0</ContainerBaseImage>
</PropertyGroup>
ContainerFamily
A partir do .NET 8, você pode usar a propriedade MSBuild para escolher uma família diferente de imagens de contêiner fornecidas pela Microsoft como a ContainerFamily
imagem base para seu aplicativo. Quando definido, esse valor é anexado ao final da tag específica do TFM selecionada, alterando a tag fornecida. Por exemplo, para usar as variantes do Alpine Linux das imagens base do .NET, você pode definir ContainerFamily
como alpine
:
<PropertyGroup>
<ContainerFamily>alpine</ContainerFamily>
</PropertyGroup>
A configuração do projeto anterior resulta em uma marca final de para um aplicativo de destino .NET 8.8.0-alpine
Este campo é de forma livre e muitas vezes pode ser usado para selecionar diferentes distribuições do sistema operacional, configurações de pacote padrão ou qualquer outro tipo de alterações em uma imagem base. Este campo é ignorado quando ContainerBaseImage
é definido. Para obter mais informações, consulte Imagens de contêiner .NET.
ContainerRuntimeIdentifier
A propriedade container runtime identifier controla o sistema operacional e a arquitetura usados pelo contêiner se o ContainerBaseImage oferecer suporte a mais de uma plataforma. Por exemplo, a mcr.microsoft.com/dotnet/runtime
imagem atualmente suporta linux-x64
, e win10-x64
imagens todas atrás da mesma tag, linux-arm
linux-arm64
então as ferramentas precisam de uma maneira de ser informado qual dessas versões você pretende usar. Por padrão, isso é definido como o valor do RuntimeIdentifier
que você escolheu quando publicou o contêiner. Essa propriedade raramente precisa ser definida explicitamente - em vez disso, use a -r
opção para o dotnet publish
comando. Se a imagem que você escolheu não suportar a que você escolheu, resultará em um erro que descreve os RuntimeIdentifiers que a RuntimeIdentifier
imagem suporta.
Você sempre pode definir a propriedade para um nome de imagem totalmente qualificado, incluindo a ContainerBaseImage
tag , para evitar a necessidade de usar essa propriedade.
<PropertyGroup>
<ContainerRuntimeIdentifier>linux-arm64</ContainerRuntimeIdentifier>
</PropertyGroup>
Para obter mais informações sobre os identificadores de tempo de execução suportados pelo .NET, consulte Catálogo RID.
ContainerRegistry
A propriedade do registro de contêiner controla o registro de destino, o local para o qual a imagem recém-criada será enviada. Por padrão, ele é enviado por push para o daemon Docker local, mas você também pode especificar um registro remoto. Ao usar um registro remoto que requer autenticação, você autentica usando os mecanismos conhecidos docker login
. Para obter mais informações, consulte a autenticação em registros de contêiner para obter mais detalhes. Para obter um exemplo concreto de uso dessa propriedade, considere o seguinte exemplo XML:
<PropertyGroup>
<ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
</PropertyGroup>
Essa ferramenta oferece suporte à publicação em qualquer registro que ofereça suporte à API HTTP V2 do Registro do Docker. Isto inclui os seguintes registos explicitamente (e provavelmente muitos mais implicitamente):
- Azure Container Registry
- Registro do Amazon Elastic Container
- Registro de artefatos do Google
- Hub do Docker
- Pacotes GitHub
- Registro de contêiner hospedado no GitLab
- Quay.io
Para obter notas sobre como trabalhar com estes registos, consulte as notas específicas do registo.
ContainerRepository
O repositório de contêiner é o nome da própria imagem, por exemplo, dotnet/runtime
ou my-app
. Por padrão, o AssemblyName
do projeto é usado.
<PropertyGroup>
<ContainerRepository>my-app</ContainerRepository>
</PropertyGroup>
ContainerImageName
O nome da imagem do contêiner controla o nome da própria imagem, por exemplo, dotnet/runtime
ou my-app
. Por padrão, o AssemblyName
do projeto é usado.
<PropertyGroup>
<ContainerImageName>my-app</ContainerImageName>
</PropertyGroup>
Nota
A partir do .NET 8, ContainerImageName
foi preterido em favor do ContainerRepository
.
Os nomes das imagens consistem em um ou mais segmentos delimitados por barras, cada um dos quais só pode conter caracteres alfanuméricos minúsculos, pontos, sublinhados e traços, e devem começar com uma letra ou número. Quaisquer outros caracteres resultam em um erro sendo lançado.
ContainerImageTag(s)
A propriedade container image tag controla as tags geradas para a imagem. Para especificar uma única tag use e para várias tags use ContainerImageTag
ContainerImageTags
.
Importante
Ao usar ContainerImageTags
o , você acabará com várias imagens, uma por tag exclusiva.
As tags geralmente são usadas para se referir a diferentes versões de um aplicativo, mas também podem se referir a diferentes distribuições do sistema operacional ou até mesmo configurações diferentes.
A partir do .NET 8, quando uma tag não é fornecida, o padrão é latest
.
Por padrão, o do projeto é usado como o Version
valor da tag.
Para substituir o padrão, especifique uma das seguintes opções:
<PropertyGroup>
<ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>
Para especificar várias tags, use um conjunto de tags delimitado por ponto-e-vírgula ContainerImageTags
na propriedade, semelhante à configuração de várias TargetFrameworks
:
<PropertyGroup>
<ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
</PropertyGroup>
As tags só podem conter até 127 caracteres alfanuméricos, pontos, sublinhados e traços. Devem começar com um caractere alfanumérico ou um sublinhado. Qualquer outro formulário resulta em um erro sendo lançado.
Nota
Ao usar ContainerImageTags
o , as tags são delimitadas por um ;
caractere. Se você estiver chamando dotnet publish
a partir da linha de comando (como é o caso com a maioria dos ambientes de CI/CD), você precisará envolver os valores em um wrap único '
e interno com aspas duplas "
, por exemplo (='"tag-1;tag-2"'
). Considere o seguinte dotnet publish
comando:
dotnet publish -p ContainerImageTags='"1.2.3-alpha2;latest"'
Isso resulta em duas imagens sendo geradas: my-app:1.2.3-alpha2
e my-app:latest
.
Gorjeta
Se você tiver problemas com a ContainerImageTags
propriedade, considere definir o escopo de uma variável ContainerImageTags
de ambiente:
ContainerImageTags='1.2.3;latest' dotnet publish
ContainerLabel
O rótulo do contêiner adiciona um rótulo de metadados ao contêiner. Os rótulos não têm impacto no contêiner em tempo de execução, mas geralmente são usados para armazenar metadados de versão e criação para uso por scanners de segurança e outras ferramentas de infraestrutura. Você pode especificar qualquer número de rótulos de contêiner.
O ContainerLabel
nó tem dois atributos:
Include
: A chave do rótulo.Value
: O valor do rótulo (pode estar vazio).
<ItemGroup>
<ContainerLabel Include="org.contoso.businessunit" Value="contoso-university" />
</ItemGroup>
Para obter uma lista de rótulos criados por padrão, consulte rótulos de contêiner padrão.
Configurar a execução de contêiner
Para controlar a execução do contêiner, você pode usar as seguintes propriedades do MSBuild.
ContainerWorkingDirectory
O nó do diretório de trabalho do contêiner controla o diretório de trabalho do contêiner, o diretório no qual os comandos são executados se nenhum outro comando for executado.
Por padrão, o valor do diretório é usado como o /app
diretório de trabalho.
<PropertyGroup>
<ContainerWorkingDirectory>/bin</ContainerWorkingDirectory>
</PropertyGroup>
ContainerPort
A porta do contêiner adiciona portas TCP ou UDP à lista de portas conhecidas para o contêiner. Isso permite que tempos de execução de contêineres, como o Docker, mapeiem essas portas para a máquina host automaticamente. Isso geralmente é usado como documentação para o contêiner, mas também pode ser usado para habilitar o mapeamento automático de portas.
O ContainerPort
nó tem dois atributos:
Include
: O número da porta a ser exposta.Type
: O padrão étcp
, os valores válidos são ouudp
tcp
.
<ItemGroup>
<ContainerPort Include="80" Type="tcp" />
</ItemGroup>
A partir do .NET 8, o ContainerPort
é inferido quando não é fornecido explicitamente com base em várias variáveis de ambiente ASP.NET bem conhecidas:
ASPNETCORE_URLS
ASPNETCORE_HTTP_PORTS
ASPNETCORE_HTTPS_PORTS
Se essas variáveis de ambiente estiverem presentes, seus valores serão analisados e convertidos em mapeamentos de porta TCP. Essas variáveis de ambiente são lidas da imagem base, se presente, ou das variáveis de ambiente definidas em seu projeto por meio ContainerEnvironmentVariable
de itens. Para obter mais informações, consulte ContainerEnvironmentVariable.
ContainerEnvironmentVariable
O nó da variável de ambiente do contêiner permite adicionar variáveis de ambiente ao contêiner. As variáveis de ambiente são acessíveis ao aplicativo em execução no contêiner imediatamente e geralmente são usadas para alterar o comportamento em tempo de execução do aplicativo em execução.
O ContainerEnvironmentVariable
nó tem dois atributos:
Include
: O nome da variável de ambiente.Value
: O valor da variável de ambiente.
<ItemGroup>
<ContainerEnvironmentVariable Include="LOGGER_VERBOSITY" Value="Trace" />
</ItemGroup>
Para obter mais informações, consulte Variáveis de ambiente .NET.
Configurar comandos de contêiner
Por padrão, as ferramentas de contêiner iniciam seu aplicativo usando o binário AppHost gerado para seu aplicativo (se seu aplicativo usa um AppHost) ou o dotnet
comando mais a DLL do seu aplicativo.
No entanto, você pode controlar como seu aplicativo é executado usando alguma combinação de ContainerAppCommand
, , ContainerDefaultArgs
ContainerAppCommandArgs
e ContainerAppCommandInstruction
.
Esses diferentes pontos de configuração existem porque diferentes imagens de base usam combinações diferentes do contêiner ENTRYPOINT
e das propriedades, e COMMAND
você deseja ser capaz de suportar todos eles. Os padrões devem ser utilizáveis para a maioria dos aplicativos, mas se você quiser personalizar o comportamento de inicialização do aplicativo, deve:
- Identifique o binário a ser executado e defina-o como
ContainerAppCommand
- Identifique quais argumentos são necessários para que seu aplicativo seja executado e defina-os como
ContainerAppCommandArgs
- Identifique quais argumentos (se houver) são opcionais e podem ser substituídos por um usuário e defina-os como
ContainerDefaultArgs
- Defina
ContainerAppCommandInstruction
comoDefaultArgs
Para obter mais informações, consulte os seguintes itens de configuração.
ContainerAppCommand
O item de configuração do comando do aplicativo é o ponto de entrada lógico do seu aplicativo. Para a maioria dos aplicativos, este é o AppHost, o binário executável gerado para seu aplicativo. Se o seu aplicativo não gerar um AppHost, esse comando normalmente será dotnet <your project dll>
. Esses valores são aplicados depois de qualquer ENTRYPOINT
um em seu contêiner base, ou diretamente se nenhum ENTRYPOINT
for definido.
A ContainerAppCommand
configuração tem uma única Include
propriedade, que representa o comando, opção ou argumento a ser usado no comando 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
Este item de configuração do comando do aplicativo args representa todos os argumentos logicamente necessários para seu aplicativo que devem ser aplicados ao ContainerAppCommand
. Por padrão, nenhum é gerado para um aplicativo. Quando presentes, os args são aplicados ao seu contêiner quando ele é executado.
A ContainerAppCommandArgs
configuração tem uma única Include
propriedade, que representa a opção ou argumento a ser aplicado ao ContainerAppCommand
comando.
<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
Este item de configuração args padrão representa quaisquer argumentos substituíveis pelo usuário para seu aplicativo. Essa é uma boa maneira de fornecer padrões que seu aplicativo pode precisar executar de uma forma que facilite a inicialização, mas ainda assim fácil de personalizar.
A ContainerDefaultArgs
configuração tem uma única Include
propriedade, que representa a opção ou argumento a ser aplicado ao ContainerAppCommand
comando.
<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
A configuração de instruções de comando do aplicativo ajuda a controlar a maneira como o , , ContainerAppCommand
, ContainerAppCommandArgs
ContainerEntrypointArgs
e ContainerDefaultArgs
são combinados para formar o ContainerEntrypoint
comando final que é executado no contêiner. Isso depende muito se um ENTRYPOINT
está presente na imagem base. Esta propriedade usa um dos três valores: "DefaultArgs"
, , "Entrypoint"
ou "None"
.
Entrypoint
:- Neste modo, o ponto de entrada é definido por
ContainerAppCommand
,ContainerAppCommandArgs
eContainerDefaultArgs
.
- Neste modo, o ponto de entrada é definido por
None
:- Neste modo, o ponto de entrada é definido por
ContainerEntrypoint
,ContainerEntrypointArgs
eContainerDefaultArgs
.
- Neste modo, o ponto de entrada é definido por
DefaultArgs
:- Este é o modo mais complexo — se nenhum dos
ContainerEntrypoint[Args]
itens estiver presente, o e será usado para criar o ponto de entrada eContainerDefaultArgs
oContainerAppCommand[Args]
comando. O ponto de entrada da imagem base para imagens base que a codificam ou/usr/bin/dotnet
são ignoradas paradotnet
que você tenha controle total. - Se ambos
ContainerEntrypoint
estiveremContainerAppCommand
presentes, entãoContainerEntrypoint
torna-se o ponto de entrada eContainerAppCommand
torna-se o comando.
- Este é o modo mais complexo — se nenhum dos
Nota
Os ContainerEntrypoint
itens e ContainerEntrypointArgs
configuração foram preteridos a partir do .NET 8.
Importante
Isso é para usuários avançados - a maioria dos aplicativos não precisa personalizar seu ponto de entrada nesse grau. Para obter mais informações e se você quiser fornecer casos de uso para seus cenários, consulte GitHub: discussões sobre compilações de contêiner do .NET SDK.
ContainerUser
A propriedade de configuração do usuário controla o usuário padrão no qual o contêiner é executado. Isso geralmente é usado para executar o contêiner como um usuário não raiz, o que é uma prática recomendada para segurança. Há algumas restrições para essa configuração estar ciente:
- Ele pode assumir várias formas: nome de usuário, IDs de usuário do linux, nome do grupo, ID do grupo do linux e outras variantes de ID
username:groupname
. - Não há nenhuma verificação de que o usuário ou grupo especificado existe na imagem.
- Alterar o usuário pode alterar o comportamento do aplicativo, especialmente em relação a coisas como permissões do sistema de arquivos.
O valor padrão deste campo varia de acordo com o TFM do projeto e o sistema operacional de destino:
- Se você estiver direcionando o .NET 8 ou superior e usando as imagens de tempo de execução da Microsoft, então:
- no Linux o usuário sem raiz é usado (embora seja referenciado por seu ID de usuário
app
) - no Windows o usuário
ContainerUser
sem raiz é usado
- no Linux o usuário sem raiz é usado (embora seja referenciado por seu ID de usuário
- Caso contrário, nenhum padrão
ContainerUser
será usado
<PropertyGroup>
<ContainerUser>my-existing-app-user</ContainerUser>
</PropertyGroup>
Gorjeta
A APP_UID
variável de ambiente é usada para definir informações do usuário em seu contêiner. Esse valor pode vir de variáveis de ambiente definidas em sua imagem base (como as imagens do Microsoft .NET) ou você mesmo pode defini-lo por meio da ContainerEnvironmentVariable
sintaxe.
No entanto, você pode controlar como seu aplicativo é executado usando ContainerEntrypoint
e ContainerEntrypointArgs
.
ContainerEntrypoint
O ponto de entrada do contêiner pode ser usado para personalizar o ENTRYPOINT
do contêiner, que é o executável que é chamado quando o contêiner é iniciado. Por padrão, para compilações que criam um host de aplicativo, ele é definido como o ContainerEntrypoint
. Para compilações que não criam um executável, o é usado como o dotnet path/to/app.dll
ContainerEntrypoint
.
O ContainerEntrypoint
nó tem um único atributo:
Include
: O comando, opção ou argumento a ser usado noContainerEntrypoint
comando.
Por exemplo, considere o seguinte grupo de itens de projeto .NET de exemplo:
<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
O nó args do ponto de entrada do contêiner controla os argumentos padrão fornecidos ao ContainerEntrypoint
. Isso deve ser usado quando o é um programa que o ContainerEntrypoint
usuário pode querer usar por conta própria. Por padrão, não ContainerEntrypointArgs
são criados em seu nome.
O ContainerEntrypointArg
nó tem um único atributo:
Include
: A opção ou argumento a ser aplicado aoContainerEntrypoint
comando.
Considere o seguinte exemplo de grupo de itens de projeto .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>
Rótulos de contêiner padrão
Os rótulos são frequentemente usados para fornecer metadados consistentes em imagens de contêiner. Este pacote fornece alguns rótulos padrão para incentivar uma melhor manutenção das imagens geradas.
org.opencontainers.image.created
está definido para o formato ISO 8601 do UTCDateTime
atual.
Para obter mais informações, consulte Implementar rótulos convencionais sobre a infraestrutura de rótulos existente.
Clean up resources (Limpar recursos)
Neste artigo, você publicou um trabalhador .NET como uma imagem de contêiner. Se desejar, exclua este recurso. Use o docker images
comando para ver uma lista de imagens instaladas.
docker images
Considere o seguinte exemplo de saída:
REPOSITORY TAG IMAGE ID CREATED SIZE
dotnet-worker-image 1.0.0 25aeb97a2e21 12 seconds ago 191MB
Gorjeta
Os arquivos de imagem podem ser grandes. Normalmente, você removeria contêineres temporários criados durante o teste e o desenvolvimento do aplicativo. Você geralmente mantém as imagens base com o tempo de execução instalado se planeja criar outras imagens com base nesse tempo de execução.
Para excluir a imagem, copie o ID da imagem e execute o docker image rm
comando:
docker image rm 25aeb97a2e21