Introdução: por que conteinerizar aplicações C#?
O desenvolvimento moderno em C# (.NET) raramente ocorre sem Docker. A conteinerização permite empacotar a aplicação junto com todas as dependências, ambiente de execução e configurações em uma imagem isolada. Isso resolve o problema "funciona na minha máquina" e simplifica a implantação em servidores, nuvem ou infraestrutura local.
Neste artigo, vamos abordar como criar uma imagem Docker para uma aplicação .NET (ASP.NET Core ou console), otimizar seu tamanho, usar docker-compose para integração com banco de dados e configurar CI/CD. Todos os exemplos de código estão escritos em C# e prontos para uso.
1. Fundamentos do Docker para desenvolvedores .NET
Docker é uma plataforma para executar aplicações em contêineres. O contêiner contém tudo que é necessário: código, ambiente de execução (runtime), bibliotecas e configurações. Para .NET, isso é especialmente conveniente, pois você não precisa instalar o .NET SDK no servidor — apenas o Docker é suficiente.
1.1. Instalação do Docker
Baixe e instale o Docker Desktop do site oficial. Após a instalação, verifique a versão:
docker --version1.2. Estrutura do projeto .NET
Suponha que temos uma aplicação simples ASP.NET Core Web API. A estrutura de pastas:
MyApp/├── MyApp.csproj├── Program.cs├── Controllers/│ └── WeatherController.cs└── Dockerfile2. Criando um Dockerfile para aplicação .NET
O Dockerfile é a instrução para construir a imagem. Para .NET, recomenda-se usar build multi-estágio (multi-stage build) para separar as etapas de compilação e execução. Isso reduz o tamanho final da imagem.
2.1. Dockerfile básico
Crie um arquivo Dockerfile na raiz do projeto:
# Estágio de compilaçãoFROM mcr.microsoft.com/dotnet/sdk:8.0 AS buildWORKDIR /srcCOPY ["MyApp.csproj", "."]RUN dotnet restoreCOPY . .RUN dotnet publish -c Release -o /app/publish
# Estágio de execuçãoFROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtimeWORKDIR /appCOPY --from=build /app/publish .EXPOSE 80ENTRYPOINT ["dotnet", "MyApp.dll"]Explicações:
- FROM ... AS build — usamos o SDK para compilação.
- COPY ["MyApp.csproj", "."] — copiamos apenas o arquivo do projeto para cachear o restore.
- RUN dotnet restore — restauramos os pacotes NuGet.
- RUN dotnet publish — compilamos a versão de release.
- FROM ... AS runtime — usamos a imagem mínima aspnet.
- EXPOSE 80 — abrimos a porta 80.
- ENTRYPOINT — comando de inicialização da aplicação.
2.2. Compilação e execução da imagem
Execute os comandos no terminal a partir da pasta do projeto:
docker build -t myapp:latest .docker run -d -p 8080:80 --name myapp_container myapp:latestAgora a aplicação está disponível em http://localhost:8080.
3. Otimização de imagens Docker para .NET
Imagens grandes retardam a implantação e consomem recursos. Aqui estão algumas práticas para otimização:
3.1. Use .NET 8 (ou superior)
Versões mais recentes do .NET possuem suporte nativo à compilação AOT (Ahead-of-Time), o que reduz o tamanho do runtime. Para ASP.NET Core, use a imagem aspnet:8.0.
3.2. Minimize as camadas
Cada instrução RUN, COPY cria uma camada. Combine comandos:
RUN apt-get update && apt-get install -y \ curl \ && rm -rf /var/lib/apt/lists/*3.3. Use .dockerignore
Crie um arquivo .dockerignore na raiz do projeto para excluir arquivos desnecessários:
bin/obj/.vs/*.user.git/README.md3.4. Exemplo de Dockerfile otimizado
FROM mcr.microsoft