Objetivo
Manter um baseline local e automatizado para Dockerfiles, Docker Compose e build real de imagens da POC, reduzindo regressao em cache, seguranca, port binding, health checks e referencias de projetos .NET.
Esta skill orienta manutencao de containers locais. Ela nao transforma o compose.yaml em manifest produtivo.
Quando usar
- Criar ou alterar Dockerfile de
*.Apiou*.Worker. - Adicionar executavel novo ao
compose.yaml. - Alterar
.csproj,ProjectReference,Directory.Build.props,Directory.Packages.propsouglobal.jsoncom impacto em container build. - Alterar
compose*.yaml,.dockerignoreou scripts de validacao de containers. - Ajustar workflow que executa
docker compose config, validadores estruturais ou build real das imagens.
Quando nao usar
- Deploy em Cloud Run, Kubernetes, VM ou outro ambiente produtivo.
- Publicar imagem, taguear release ou fazer push para registry.
- Corrigir regra de negocio, endpoint HTTP, evento, persistencia ou mensageria sem impacto nos containers.
- Adicionar hardening generico sem requisito, validacao ou risco concreto.
Principios obrigatorios
- Um Dockerfile por executavel publicado, ao lado do
.csprojde*.Apiou*.Worker. - Dockerfiles devem usar multi-stage build.
- APIs usam imagem final
mcr.microsoft.com/dotnet/aspnet:<tag>. - Workers usam imagem final
mcr.microsoft.com/dotnet/runtime:<tag>. - SDK fica apenas no estagio de build.
global.jsondeve ser copiado antes do restore.Directory.Packages.propseDirectory.Build.propsdevem ser copiados antes do restore.- Todos os
ProjectReferencediretos e transitivos devem estar disponiveis antes do restore. - A copia de projetos deve ser seletiva; nao use
COPY . .antes do restore. - Use cache BuildKit para NuGet em
dotnet restoreedotnet publish. dotnet publishdeve usar--no-restore.dotnet publishdeve usar/p:UseAppHost=false.- A imagem final deve executar sem root.
- O usuario final aprovado para as imagens .NET deste repositorio e
USER $APP_UID. - Copias do estagio final devem usar
COPY --chown=$APP_UID:0. - Nenhuma secret deve entrar por
ARG,ENV, imagem ou contexto de build. - Nenhuma imagem pode ficar sem tag ou digest explicito.
- A tag
lateste proibida. - Portas publicadas localmente devem fazer bind em
127.0.0.1. container_namee proibido.- Servicos HTTP da aplicacao precisam de health check.
depends_onpode ordenar startup local, mas nao substitui timeout, retry, readiness, idempotencia ou resiliencia da aplicacao.- Compose local nao e diretamente promovivel para producao.
- CI deve validar as imagens com build real; teste estrutural sozinho nao prova que restore, publish e runtime fecham.
Checklist para adicionar um novo executavel
- Crie o projeto em
src/<contexto>/<Nome>.Apiousrc/<contexto>/<Nome>.Worker. - Adicione um Dockerfile ao lado do
.csproj. - Use
aspnetpara API eruntimepara Worker no estagio final. - Copie
Directory.Packages.props,Directory.Build.propseglobal.jsonantes do restore. - Copie o
.csprojdo executavel e todos osProjectReferencediretos e transitivos antes do restore. - Copie apenas os diretorios de codigo necessarios antes do publish.
- Publique com
--no-restoree/p:UseAppHost=false. - Rode com
USER $APP_UIDe useCOPY --chown=$APP_UID:0. - Adicione o servico ao Compose com build, limites locais, redes, variaveis e health check quando for HTTP.
- Rode o validador estrutural e o build real de Compose.
Checklist para alterar um .csproj
- Verifique se o projeto e executavel ou dependencia de executavel containerizado.
- Se adicionar/remover
ProjectReference, atualize os Dockerfiles que publicam projetos dependentes. - Confirme que o
.csprojreferenciado e copiado antes do restore. - Confirme que o diretorio de codigo referenciado e copiado antes do publish.
- Rode
dotnet run --project tools/ContainerBaselineValidator/ContainerBaselineValidator.csproj -- --root .. - Rode pelo menos os testes arquiteturais afetados.
Checklist para adicionar um novo ProjectReference
- Identifique todos os executaveis que dependem direta ou transitivamente do projeto alterado.
- Para cada Dockerfile afetado, adicione
COPY <referencia>.csproj <diretorio>/antes do restore. - Adicione
COPY <diretorio>/ ./<diretorio>/antes do publish. - Nao resolva falha de restore com
||, restore duplicado ouCOPY . .amplo. - Rode o validador estrutural; a mensagem deve apontar o projeto ausente e a origem da dependencia se algo faltar.
Checklist para alterar o Compose
- Rode
docker compose -f compose.yaml config --quiet. - Garanta imagens com tag explicita e sem
latest. - Nao use
container_name. - Publique portas somente em
127.0.0.1. - Declare variaveis de portas em
.env.local.example. - Se o servico HTTP da aplicacao for definido por build, mantenha health check para
/ready. - Preserve limites locais de
cpus,memoryepidsnos servicos cobertos pela politica. - Se usar
build.dockerfileoubuild.target, confirme que o caminho e o stage existem. - Rode o validador estrutural.
- Rode build real das imagens do Compose.
Procedimento de validacao
dotnet run --project tools/ContainerBaselineValidator/ContainerBaselineValidator.csproj -- --root .
dotnet run --project tools/ContainerBaselineValidator/ContainerBaselineValidator.csproj -- --root . --self-test-invalid
docker compose -f compose.yaml config --quiet
docker compose -f compose.yaml build
dotnet test ./LedgerService.slnx --configuration Release --filter FullyQualifiedName~ContainerSecurityPolicyTests
No CI, a validacao de container deve:
- executar
docker compose config --quiet; - executar o validador estrutural;
- construir todas as imagens definidas pelo Compose;
- usar cache de build quando apropriado;
- nao usar secrets reais;
- nao publicar imagens e nao fazer push para registry.
Antipadroes e exemplos concretos
Restore mascarado
RUN dotnet restore src/ledger/LedgerService.Api/LedgerService.Api.csproj || dotnet restore src/ledger/LedgerService.Api/LedgerService.Api.csproj
Corrija as copias de .csproj e ProjectReference antes do restore.
Projeto referenciado ausente antes do restore
COPY src/ledger/LedgerService.Api/LedgerService.Api.csproj src/ledger/LedgerService.Api/
RUN dotnet restore src/ledger/LedgerService.Api/LedgerService.Api.csproj
Se a API referencia Application, Domain, Infrastructure ou Shared, copie todos os .csproj antes do restore.
Imagem final errada
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS final
Use aspnet para API e runtime para Worker no estagio final.
Porta aberta no host
ports:
- "${LEDGER_SERVICE_HOST_PORT:-5226}:8080"
Use:
ports:
- "127.0.0.1:${LEDGER_SERVICE_HOST_PORT:-5226}:8080"
depends_on tratado como resiliencia
depends_on:
postgres-db:
condition: service_healthy
Isso ajuda a ordem local, mas a aplicacao ainda precisa lidar com indisponibilidade, timeout, retry e readiness.
Referencias oficiais consultadas
- Docker Build best practices: https://docs.docker.com/build/building/best-practices/
- Docker multi-stage builds: https://docs.docker.com/build/building/multi-stage/
- Docker build cache optimization: https://docs.docker.com/build/cache/optimize/
- Docker build secrets: https://docs.docker.com/build/building/secrets/
- Dockerfile
HEALTHCHECK: https://docs.docker.com/reference/dockerfile/#healthcheck - Docker Compose Specification: https://compose-spec.github.io/compose-spec/spec.html
- Docker Compose services reference: https://docs.docker.com/reference/compose-file/services/
- Docker Compose secrets: https://docs.docker.com/compose/how-tos/use-secrets/
- Microsoft .NET container images: https://learn.microsoft.com/en-us/dotnet/core/docker/container-images
- Microsoft .NET container app tutorial: https://learn.microsoft.com/en-us/dotnet/core/docker/build-container
- Microsoft .NET non-root
appuser andAPP_UID: https://learn.microsoft.com/en-us/dotnet/core/compatibility/containers/8.0/app-user - GitHub Actions publishing Docker images: https://docs.github.com/en/actions/tutorials/publish-packages/publish-docker-images
- Docker GitHub Actions build cache: https://docs.docker.com/build/ci/github-actions/cache/