Colocar em contêiner um aplicativo .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 habilitar a 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á a colocar em contêiner um aplicativo .NET usando o comando dotnet publish sem o uso de um Dockerfile. Além disso, você explora como configurar a imagem de contêiner e, executar processos, e como limpar os recursos.
Dica
Se você estiver interessado em usar um dockerfile para colocar seu aplicativo .NET em contêineres, consulte Tutorial: Conteinerizar um aplicativo .NET.
Pré-requisitos
Instale os seguintes pré-requisitos:
- SDK do .NET 8+
Se você tiver o .NET instalado, use o comandodotnet --info
para determinar qual SDK você está usando.
Se você planeja executar o contêiner localmente, precisará de um runtime de contêiner compatível com OCI (Open Container Initiative), como:
- Docker Desktop: o runtime de contêiner mais comum.
- Podman: uma alternativa de software livre ao Docker, sem daemon.
Importante
O SDK do .NET cria imagens de contêiner sem o Docker. Docker ou Podman só serão necessários se você quiser executar a imagem localmente. Por padrão, quando você publica seu aplicativo .NET como uma imagem de contêiner, ele é enviado por push para um runtime de contêiner local. Como alternativa, você pode salvar a imagem como um tarball ou enviá-la diretamente para um registro de contêiner sem usar nenhum runtime de contêiner.
Além desses pré-requisitos, é recomendável que você esteja familiarizado com os Serviços de Trabalho no .NET, pois o projeto de exemplo é um trabalhador.
Criar um aplicativo .NET
Você precisa de um aplicativo .NET para contêineres, portanto, comece criando um novo aplicativo a partir de um modelo. Abra o terminal, crie uma pasta de trabalho (de diretório de exemplo) se ainda não tiver feito isso 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
A árvore de pastas é semelhante ao seguinte diretório:
📁 sample-directory
└──📂 Worker
├──appsettings.Development.json
├──appsettings.json
├──DotNet.ContainerImage.csproj
├──Program.cs
├──Worker.cs
├──📂 Properties
│ └─── launchSettings.json
└──📂 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 comando dotnet new
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 Worker. Use o comando dotnet run
para iniciar o aplicativo.
dotnet run
Using launch settings from ./Worker/Properties/launchSettings.json...
Building...
info: DotNet.ContainerImage.Worker[0]
Worker running at: 01/06/2025 13:37:28 -06: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: 01/06/2025 13:37:29 -06:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 01/06/2025 13:37:30 -06:00
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
O modelo do trabalhador se repete indefinidamente. Use o comando cancelar Ctrl+C para pará-lo.
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>net9.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="9.0.1" />
</ItemGroup>
</Project>
Para obter mais referências, consulte ContainerRepository
.
Publicar aplicativo .NET
Para publicar o aplicativo .NET como um contêiner, use o seguinte comando dotnet publish:
dotnet publish --os linux --arch x64 /t:PublishContainer
O comando anterior da CLI do .NET publica o aplicativo como um contêiner:
- Direcionar o Linux como o sistema operacional (
--os linux
). - Especificando uma arquitetura x64 (
--arch x64
).
Importante
Para publicar o contêiner localmente, você deve ter um daemon em conformidade com OCI ativo em execução. Se ele não estiver em execução quando você tentar publicar o aplicativo como um contêiner, você terá um erro semelhante ao seguinte:
..\build\Microsoft.NET.Build.Containers.targets(66,9): error MSB4018:
The "CreateNewImage" task failed unexpectedly. [..\Worker\DotNet.ContainerImage.csproj]
O comando dotnet publish
produz uma saída semelhante à saída de exemplo:
Restore complete (0.2s)
DotNet.ContainerImage succeeded (2.6s) → bin\Release\net9.0\linux-x64\publish\
Esse comando compila seu aplicativo worker para a pasta de publicação e envia a imagem do contêiner para o daemon local do Docker, por padrão. Se você estiver usando o Podman, um alias
Publicar o aplicativo .NET em um tarball
Um tarball (ou arquivo tar) é um arquivo que contém outros arquivos. Geralmente, ele termina com uma extensão de arquivo *.tar.gz composta para ajudar a indicar que é um arquivo compactado. Esses tipos de arquivo são usados para distribuir software ou para criar backups. Nesse caso, o tarball criado é usado para distribuir uma imagem de contêiner.
Para publicar um aplicativo .NET como um contêiner em um tarball, use o seguinte comando:
dotnet publish --os linux --arch x64 \
/t:PublishContainer \
-p ContainerArchiveOutputPath=./images/container-image.tar.gz
O comando anterior publica o aplicativo como um contêiner para um arquivo tar:
- Direcionar o Linux como o sistema operacional (
--os linux
). - Especificando uma arquitetura x64 (
--arch x64
). - Definindo a propriedade
ContainerArchiveOutputPath
como./images/container-image.tar.gz
.
O comando não requer um daemon em conformidade com OCI em execução. Para obter mais informações, consulte ContainerArchiveOutputPath
.
Carregar o tarball
Um caso de uso comum para exportar para um tarball é para organizações focadas em segurança. Eles criam contêineres, os exportam como tarballs e, em seguida, executam ferramentas de verificação de segurança nos tarballs. Essa abordagem simplifica a conformidade, pois evita as complexidades da verificação de um sistema ativo.
O tarball contém todo o contêiner, que pode ser carregado usando a ferramenta apropriada:
- Docker:
docker load -i ./images/container-image.tar.gz
- Podman:
podman load -i ./images/container-image.tar.gz
Publicar aplicativo .NET no registro de contêiner
Os registros de contêiner são serviços que armazenam e gerenciam imagens de contêiner. Eles são usados para armazenar e distribuir imagens de contêiner em vários ambientes. Você pode publicar um aplicativo .NET como um contêiner em um registro de contêiner usando o seguinte comando:
dotnet publish --os linux --arch x64 \
/t:PublishContainer \
-p ContainerRegistry=ghcr.io
O código anterior publica o aplicativo como um contêiner em um registro de contêiner:
- Direcionar o Linux como o sistema operacional (
--os linux
). - Especificando uma arquitetura x64 (
--arch x64
). - Definindo a propriedade
ContainerRegistry
comoghcr.io
.
Para obter mais informações, consulte ContainerRegistry.
Limpar recursos
Neste artigo, você publicou um trabalho do .NET como uma imagem de contêiner. Se desejar, exclua esse recurso. Use o comando docker images
para ver uma lista de imagens instaladas.
docker images
Considere a seguinte saída de exemplo:
REPOSITORY TAG IMAGE ID CREATED SIZE
dotnet-worker-image 1.0.0 25aeb97a2e21 12 seconds ago 191MB
Dica
Os arquivos de imagem podem ser grandes. Normalmente, você removeria contêineres temporários criados durante o teste e o desenvolvimento do aplicativo. Normalmente, você mantém as imagens base com o runtime instalado se planeja criar outras imagens com base nesse runtime.
Para excluir a imagem, copie a ID da imagem e execute o comando docker image rm
:
docker image rm 25aeb97a2e21