Containerização de aplicações C# em Docker: nível avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que nível avançado?

\n

A containerização de aplicações C# baseadas em .NET deixou de ser apenas uma tendência — é um padrão industrial. No nível inicial, um Dockerfile básico com FROM mcr.microsoft.com/dotnet/aspnet é suficiente. No entanto, em ambientes de produção, surgem desafios que exigem um entendimento mais profundo: minimização do tamanho da imagem, segurança, arquitetura multi-contêiner, gerenciamento eficiente de configuração e depuração.

\n

Este artigo é destinado a desenvolvedores que já conhecem os fundamentos do Docker e C#, mas desejam avançar para o próximo nível. Abordaremos técnicas avançadas que permitirão criar imagens leves, seguras e facilmente escaláveis para suas aplicações .NET.

\n\n

1. Compilação multi-estágio (Multi-stage build): a arte das imagens leves

\n

Um problema clássico — as imagens do .NET SDK pesam mais de 1,5 GB. Levá-las para produção é inútil e perigoso. A compilação multi-estágio resolve esse problema, separando a etapa de compilação da etapa de execução.

\n\n

Dockerfile avançado com multi-stage

\n

Em vez de simplesmente copiar os arquivos binários, usamos as imagens oficiais do SDK para compilar e, em seguida, copiamos o resultado para a imagem mínima aspnet.

\n
# Etapa 1: Compilação\nFROM mcr.microsoft.com/dotnet/sdk:8.0 AS build\nWORKDIR /app\n\n# Copiamos apenas os arquivos do projeto (otimização de cache)\nCOPY src/MyApp.csproj .\nRUN dotnet restore\n\n# Copiamos o restante do código\nCOPY src/ .\nRUN dotnet publish -c Release -o /app/publish\n\n# Etapa 2: Runtime\nFROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime\nWORKDIR /app\n\n# Adicionamos um usuário não privilegiado\nRUN adduser --disabled-password --gecos '' appuser\nUSER appuser\n\nCOPY --from=build /app/publish .\n\nEXPOSE 8080\nENV ASPNETCORE_URLS=http://+:8080\nENTRYPOINT ["dotnet", "MyApp.dll"]
\n

O que é importante aqui:

\n
    \n
  • Cache de camadas: primeiro copiamos apenas o .csproj e executamos dotnet restore. Enquanto as dependências não mudarem, o Docker usará o cache para esta camada.
  • \n
  • Usuário não privilegiado: appuser — é criticamente importante para a segurança em produção.
  • \n
  • Porta 8080: no .NET 8, a porta padrão é 8080, alinhada com os padrões modernos de nuvem.
  • \n
\n\n

Dica: Compilação Trimmed e AOT

\n

Para reduzir ainda mais o tamanho, use Trimming (remoção de código não utilizado) ou Native AOT. Isso permite obter imagens de 10 a 30 MB.

\n
# Para ReadyToRun (R2R) e Trimming\nRUN dotnet publish -c Release -r linux-x64 --self-contained true \\\n    -p:PublishTrimmed=true \\\n    -p:PublishSingleFile=true \\\n    -o /app/publish
\n

Importante: AOT impõe restrições à reflexão e ao carregamento dinâmico de assemblies. Antes de usar, certifique-se de que seu código é compatível.

\n\n

2. Gerenciamento de configuração e segredos

\n

Armazenar strings de conexão e chaves de API dentro da imagem é um erro grave. No nível avançado, usamos Docker Secrets, variáveis de ambiente e integração com appsettings.json.

\n\n

Sobrescrevendo appsettings via Docker

\n

O .NET possui um mecanismo interno de prioridades de configuração. Podemos passar configurações através de variáveis de ambiente, que são mapeadas automaticamente para as seções de configuração.

\n
// No código C#\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Configuration\n    .AddJsonFile("appsettings.json", optional: false)\n    .AddEnvironmentVariables(); // Sobrescreve valores do JSON
\n

Executamos o contêiner:

\n
docker run -d -p 8080:8080 \\\n  -e "ConnectionStrings__DefaultConnection=Server=db;Database=myapp;User Id=sa;Password=MyPass123!" \\\n  -e "Logging__LogLevel__Default=Warning" \\\n                

Blogs

Book Recommendations