A segurança do Docker costuma ser uma reflexão tardia até que ocorra uma violação. Em 2026, executar contêineres como root, usar imagens não verificadas e expor portas desnecessárias estão entre os erros mais comuns de segurança de produção. Este guia aborda o fortalecimento da segurança do Docker, do Dockerfile ao tempo de execução.
📋 Table of Contents
Os principais riscos de segurança do Docker
- Executando contêineres como usuário root
- Usando imagens base desatualizadas com CVEs conhecidos
- Codificando segredos em imagens ou redigindo arquivos
- Expondo o soquete daemon do Docker
- Usando a tag mais recente (versões não fixadas)
- Capacidades excessivamente permissivas
- Sem limites de recursos (CPU/memória)
Padrões Dockerfile seguros
# SECURE: Multi-stage, minimal base, non-root user
FROM python:3.12-slim AS builder
# Pin all package versions
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt && pip install pip-audit && pip-audit # fail build if known CVEs
FROM gcr.io/distroless/python3-debian12 # minimal, no shell
# OR use: python:3.12-slim (if you need shell for debugging)
# Never run as root
RUN groupadd -r appgroup && useradd -r -g appgroup -u 1001 appuser
WORKDIR /app
# Copy only what's needed
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --chown=appuser:appgroup src/ .
# Declare what's sensitive (documentation, not actual protection)
# NEVER put actual secrets here
ENV APP_ENV=production
USER appuser # non-root!
# Make filesystem read-only (app should write to /tmp or mounted volumes)
VOLUME ["/tmp", "/var/run"]
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Gerenciamento de segredos
# WRONG: secrets in compose file
services:
app:
environment:
DB_PASSWORD: mysecretpassword # visible in 'docker inspect'!
# CORRECT: use Docker secrets or env file
services:
app:
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt # .gitignore this!
# OR for Docker Swarm:
# external: true
# Never embed secrets in images!
# Bad: COPY .env /app/.env
# Bad: ENV DB_PASSWORD=secret
# Good: pass at runtime
docker run -e DB_PASSWORD="$(cat ~/.secrets/db_password)" myapp
# Better: use a secret manager
# AWS Secrets Manager, HashiCorp Vault, Azure Key Vault
# Check for leaked secrets
docker history --no-trunc myimage:latest | grep -i secret
docker inspect myimage | grep -i password
Segurança de tempo de execução
# compose.yaml — secure runtime config
services:
app:
image: myapp:1.2.3 # pin exact version!
read_only: true # read-only root filesystem
tmpfs:
- /tmp:size=100m,noexec # writable temp, no execution
security_opt:
- no-new-privileges:true # prevent privilege escalation
cap_drop:
- ALL # drop all capabilities
cap_add:
- NET_BIND_SERVICE # add only what's needed
user: "1001:1001" # non-root UID:GID
ulimits:
nofile:
soft: 1024
hard: 2048
mem_limit: 512m
cpus: '1.0'
networks:
- backend # isolated network
# Never expose Docker socket:
# volumes:
# - /var/run/docker.sock:/var/run/docker.sock # DANGEROUS!
networks:
backend:
driver: bridge
internal: true # no external access
Digitalização de imagens
# Trivy — fast, free vulnerability scanner
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:latest image --severity HIGH,CRITICAL myapp:latest
# Docker Scout (built into Docker Desktop 2024+)
docker scout cves myapp:latest
docker scout recommendations myapp:latest
# Snyk
snyk container test myapp:latest
# In CI/CD pipeline
name: Security Scan
on: [push]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: sarif
exit-code: '1' # fail on HIGH/CRITICAL
severity: 'HIGH,CRITICAL'
Segurança de rede
# Use user-defined networks (not default bridge)
docker network create --driver bridge --subnet 172.20.0.0/16 appnet
# Verify containers can't reach each other on default network
# By default, containers on same network CAN reach each other
# Use 'internal: true' to prevent external access
# Limit exposed ports
# WRONG: 0.0.0.0:5432:5432 (exposed to all interfaces)
# CORRECT: 127.0.0.1:5432:5432 (localhost only)
# Or don't expose at all — access via internal network name
Lista de verificação de segurança do Docker
- Usuário não root no Dockerfile
- Versões de imagens fixadas (não: mais recentes)
- Construção em vários estágios (imagem final mínima)
- Sem segredos nas imagens ou no ambiente de composição
- Sistema de arquivos raiz somente leitura
- Elimine todos os recursos, adicione apenas os necessários
- Limites de recursos definidos (memória/CPU)
- Imagem digitalizada com Trivy ou Snyk antes da implantação
- Soquete Docker não montado em contêineres
- Redes isoladas por nível de serviço
- Segredos via segredos do Docker ou cofre (nunca env vars)
Segurança do Docker em 2026: o modelo de ameaça é real – fugas de contêineres, vazamentos de segredos e escalonamento de privilégios são vetores de ataque documentados. Implemente usuários não-root, sistemas de arquivos somente leitura, varredura de imagens em CI e gerenciamento de segredos adequado antes de entrar em produção. O esforço é mínimo comparado ao risco de uma violação.
🔗 Share this article
✍️ Leave a Comment