Segurança em containers Docker: práticas essenciais
Docker não isola containers do host da mesma forma que uma VM. Um container rodando como root com acesso ao socket Docker pode comprometer todo o servidor. As práticas mais importantes: nunca expor /var/run/docker.sock para containers não confiáveis, nunca rodar processos como root dentro de containers quando evitável, configurar limites de recursos e usar imagens de fontes verificadas.
Rodar containers como usuário não-root
Containers que rodam como root têm permissões iguais ao root do host se o container for comprometido. Use usuários não-root sempre que possível:
# No Dockerfile — criar usuário e trocar antes do CMD
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm ci --production
# Cria usuário com UID fixo e sem home
RUN addgroup -g 1001 -S appgroup && adduser -u 1001 -S appuser -G appgroup
USER appuser
CMD ["node", "server.js"]
# No docker-compose.yml — forçar usuário via Compose
services:
app:
image: minha-app:latest
user: "1001:1001"Nunca expor o Docker socket em containers não confiáveis
Montar /var/run/docker.sock dentro de um container dá controle total sobre o Docker daemon — e por extensão, sobre todo o servidor:
# PERIGO — nunca faça isso para containers de usuários finais ou workloads não confiáveis:
volumes:
- /var/run/docker.sock:/var/run/docker.sock # controle total do Docker!
# QUANDO é necessário (ex.: Portainer, Traefik, CI runners):
# Restrinja com read-only quando possível:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
# Alternativa mais segura: Portainer Agent (proxy com permissões restritas)
# ao invés de montar o socket diretamenteFilesystem read-only e capabilities
Containers com filesystem somente leitura e capabilities reduzidas têm superfície de ataque muito menor:
services:
app:
image: minha-app:latest
read_only: true # filesystem imutável (exceto volumes montados)
tmpfs:
- /tmp # área de escrita temporária se necessário
security_opt:
- no-new-privileges:true # processo não pode ganhar mais privilégios que o pai
cap_drop:
- ALL # remove todas as capabilities Linux
cap_add:
- NET_BIND_SERVICE # adiciona de volta apenas o que for necessárioLimitar recursos para isolar falhas
Sem limites de recursos, um container com bug (memory leak, loop infinito) pode consumir toda a CPU e RAM do host, derrubando os demais serviços:
services:
app:
image: minha-app:latest
deploy:
resources:
limits:
memory: 512M # container morto (OOMKilled) se ultrapassar
cpus: '1.0' # máximo 1 core (pode usar frações)
reservations:
memory: 256M # garante pelo menos 256MB disponíveis
cpus: '0.25' # reserva 0.25 core
# Limite de processos (previne fork bombs)
worker:
image: worker:latest
ulimits:
nproc: 100 # máximo 100 processos dentro do containerUsar imagens verificadas e atualizadas
Imagens desatualizadas contêm vulnerabilidades conhecidas. Práticas para manter imagens seguras:
# Usar imagens oficiais (Docker Hub "Official Image" badge)
# Preferir variantes slim/alpine (menor superfície)
FROM node:20-alpine # menor footprint que node:20
FROM python:3.11-slim # melhor que python:3.11 (full)
# Verificar vulnerabilidades com docker scout (CLI)
docker scout cves nome_da_imagem:tag
# Atualizar imagens regularmente
docker compose pull # baixa versões atualizadas das imagens fixadas
# Verificar digest para garantir integridade
docker pull postgres:16@sha256:abc123... # imagem imutável via digest$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o Docker em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.