Docker virou sinônimo de containerização — e por boas razões. Mas há uma diferença enorme entre rodar containers em desenvolvimento e operá-los com segurança em produção. Este guia cobre as práticas essenciais e os erros mais comuns encontrados em ambientes de PMEs brasileiras.
Por que Docker em produção exige atenção especial?
Em desenvolvimento, containers são descartáveis e convenientes. Em produção, eles precisam ser seguros, resilientes, observáveis e eficientes. A maioria dos problemas vem de configurações padrão que fazem sentido em dev mas são perigosas em prod.
1. Nunca rode containers como root
O erro mais comum — e mais perigoso. Por padrão, processos dentro de um container rodam como root. Sempre especifique um usuário não-root no Dockerfile:
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --chown=appuser:appgroup . .
RUN npm ci --only=production
USER appuser
CMD ["node", "server.js"]
2. Use imagens base mínimas
Imagens grandes têm mais superfície de ataque. Prefira variantes alpine ou distroless e verifique vulnerabilidades antes de usar em produção:
# Scan de vulnerabilidades com Trivy (gratuito)
trivy image node:20-alpine
3. Configure limites de recursos
Sem limites definidos, um container pode consumir toda a CPU e memória do host, derrubando outros serviços:
# docker-compose.yml
services:
app:
image: minha-app:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
4. Política de restart correta
services:
app:
restart: unless-stopped # Reinicia sempre, exceto quando parado manualmente
Evite restart: always em containers que podem entrar em loop de crash.
5. Volumes e persistência de dados
Dados importantes nunca devem ficar dentro do container — ele é efêmero por natureza:
services:
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
6. Nunca coloque segredos em variáveis de ambiente ou Dockerfile
# NUNCA faça isso
ENV DB_PASSWORD=minhasenhasecreta
Use arquivos .env fora do repositório e jamais os commite no git. Em produção com Swarm, use o mecanismo de secrets nativo:
echo "minhasenhasecreta" | docker secret create db_password -
7. Rede: isole seus containers
services:
app:
networks: [frontend, backend]
db:
networks: [backend] # Banco acessível apenas pela rede backend
nginx:
networks: [frontend]
networks:
frontend:
backend:
internal: true
8. Health checks
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
Checklist de produção
- ☐ Container roda com usuário não-root
- ☐ Imagem base mínima (alpine ou distroless)
- ☐ Limites de CPU e memória definidos
- ☐ Política de restart configurada
- ☐ Dados persistidos em volumes externos
- ☐ Segredos gerenciados fora do Dockerfile
- ☐ Redes isoladas por função
- ☐ Health check implementado
- ☐ Scan de vulnerabilidades na pipeline de CI/CD
Referências
- Docker. Docker Security Best Practices. Disponível em: docs.docker.com
- OWASP. Docker Security Cheat Sheet. Disponível em: cheatsheetseries.owasp.org
- Aqua Security. Trivy — Container Vulnerability Scanner. Disponível em: github.com/aquasecurity/trivy