Estabilidade em contentores é resultado de previsibilidade: builds repetíveis, execução com limites claros, dependências explícitas, observabilidade simples e rotinas de manutenção que não dependem de heróis. Em 2024–2025, dá para atingir isso sem complicar: imagens pequenas e reproduzíveis, execução sem privilégios, rede e dados isolados, atualizações que não derrubam o serviço e rollbacks que cabem num comando. O objetivo deste guia é prático: padronizar ambientes, evitar conflitos e manter o host limpo, para que “arrancar e otimizar” signifique, na prática, menos incidentes e recuperação mais rápida quando algo falha.
Imagens reprodutíveis e pequenas: menos variação, menos CVEs

Comece pelo Dockerfile ou equivalente com multi-stage build: compilar numa imagem “cheia” e copiar só os artefactos para uma base minimal (slim, distroless ou runtime-only). Fixe versões do SO e de bibliotecas; não use comandos de atualização genéricos que variam a cada build. Defina USER não-root e mantenha o sistema de ficheiros em read-only, escrevendo apenas em volumes claramente montados. Ordene cópias e instalações para maximizar cache, documente variáveis de ambiente e escolha um único diretório de trabalho. Gere um SBOM a cada build e integre scan de vulnerabilidades no pipeline, bloqueando versões com CVEs críticos antes de subir ao registo. Etiquete imagens com esquema estável (ex.: app:1.8.2 e app:1.8.2-), usando digests em produção para evitar “latest” enganadores.
Execução previsível: limites, sinais e isolamento
No runtime, privilegie o mínimo de privilégios. Remova capabilities que não precisa, desligue privilégios elevados e isole PID/IPC do host. Aplique limites de CPU e memória compatíveis com o perfil real; reserve também recursos quando possível para evitar contendas. Garanta que o processo PID 1 gere sinais corretamente e “recolhe” zumbis; um init leve (tini) resolve muitos shutdowns lentos. Mantenha healthchecks que testem a app a sério (consulta a endpoint interno ou comando de verificação), em vez de apenas “porta aberta”. Redirecione logs para stdout/stderr em formato estruturado e deixe a rotação para o daemon/sidecar; não escreva logs infinitos no disco do contentor. Para jobs efémeros, use contentores que arrancam, trabalham e terminam, evitando processos órfãos e diretórios sujos.
Rede, dados e segredos: cada coisa no seu lugar
Trate a rede como fronteira de estabilidade. Use redes virtuais internas para comunicação entre serviços e exponha ao exterior apenas através de um proxy/reverso. Evite publicar portas em 0.0.0.0 sem necessidade e prefira nomes de serviço em vez de IPs para reduzir acoplamento. Dados são responsabilidade de volumes, não de imagens: defina caminhos de escrita explícitos, use volumes com backup e versionamento, e separe configuração de estado para facilitar rollbacks. Migrações de base devem ser idempotentes e executadas antes de expor a nova versão; se houver passos destrutivos, faça “expandir → migrar → cortar” com compatibilidade temporária. Segredos nunca vivem na imagem nem em repositórios; injete-os via mecanismos de secrets do runtime, com escopo mínimo e rotação periódica. Para diretórios temporários, monte tmpfs e limite tamanho para evitar encher discos por engano.
Atualizações seguras e reversão em segundos
Promova a mesma imagem entre dev, staging e produção, alterando apenas variáveis e endpoints. Em uma única máquina, faça blue/green: levante a nova pilha em portas internas, passe readiness, troque o tráfego no proxy e mantenha a antiga “em espera” por alguns minutos. Em clusters, use rollouts graduais com limites de réplicas atualizadas, janelas de readiness e backoff em falhas; canary ajuda a detectar regressões cedo. Defina tempos de terminationGracePeriod compatíveis com shutdown limpo e configure liveness só depois de ter readiness afinado, para não matar instâncias em arranques lentos. Tenha um comando de rollback documentado e testado; guardar as duas últimas versões prontas a arrancar reduz o MTTR para segundos. Evite dependências em “latest” no registo; fixe digests e implemente retenção automática para imagens antigas, além de limpeza de camadas não usadas no host.
Observabilidade e higiene contínua: estabilidade que se renova

Exponha métricas básicas (latência, taxa de erro, filas, uso de CPU/memória/IO) e um endpoint de health que reflete dependências essenciais. Correlacione logs com um request_id de entrada para atravessar serviços. Alerta por tendência, não só por pico: crescimento de uso de memória ou de “restarts” é sinal de fuga ou limites mal ajustados. No host, agende “prune” seguro de imagens sem referência, volumes órfãos e caches antigos; em registos privados, ative políticas de retenção e assinatura/proveniência. Documente em poucas linhas como correr localmente, como parametrizar credenciais, como executar migrações e como reverter; documentação viva reduz dependência de conhecimento tácito. Uma revisão quinzenal que passa por scans, tamanhos de imagens, tempos de arranque, taxas de falha de healthcheck e consumo médio por serviço mantém a plataforma previsível e o custo sob controlo.

Leave a Reply