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á 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 o e a execução da imagem do contêiner
Dica
Se você estiver interessado em usar um Dockerfile para colocar em contêiner seu aplicativo .NET, consulte Tutorial: Containerize 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 tempo de execução de contêiner compatível com Open Container Initiative (OCI), como:
- Docker Desktop: Tempo de execução de contêiner mais comum.
- Podman: Uma alternativa de código aberto e sem daemon ao Docker.
Importante
O SDK do .NET cria imagens de contêiner sem o Docker. Docker ou Podman só são necessários se você quiser executar a imagem localmente. Por padrão, quando você publicar seu aplicativo .NET como uma imagem de contêiner, ele é enviado por push para um tempo de execução de contêiner local. Como alternativa, você pode salvar a imagem
Além desses pré-requisitos, é recomendável que você esteja familiarizado com Worker Services no .NET, pois o projeto de exemplo é um trabalhador.
Criar aplicativo .NET
Você precisa de um aplicativo .NET para criar contêineres, então comece criando um novo aplicativo a partir de um modelo. Abra seu 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 é 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 do 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 de trabalho é executado indefinidamente. Use o comando cancel 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 mais informações, ver 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:
- Visando 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 compatível 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ê enfrentará 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\
Este comando compila seu aplicativo de trabalho para a pasta publish e envia a imagem do contêiner para o daemon Docker local por padrão. Se estiver a utilizar o Podman, um alias
Publicar aplicação .NET num tarball
Um tarball (ou arquivo tar) é um arquivo que contém outros arquivos. Ele geralmente termina com uma extensão de arquivo composto *.tar.gz 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 a aplicação como um contêiner num tarball.
- Visando 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 compatível com OCI em execução. Para obter mais informações, consulte ContainerArchiveOutputPath
.
Carregue o arquivo tar
Um caso de uso comum para exportar para um tarball é para organizações focadas em segurança. Eles criam contentores, exportam-nos como ficheiros tar e, em seguida, executam ferramentas de varredura de segurança sobre eles. Essa abordagem simplifica a conformidade, pois evita as complexidades da verificação de um sistema ativo.
O tarball contém todo o contenedor, que pode então 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 o aplicativo .NET no registro do 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:
- Visando 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 trabalhador .NET como uma imagem de contêiner. Se desejar, exclua este recurso. Use o comando docker images
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
Dica
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 comando docker image rm
:
docker image rm 25aeb97a2e21