Docker seguro em produção na VPS
Docker com configuração padrão tem vários riscos de segurança: containers rodando como root, imagens com vulnerabilidades conhecidas, portas expostas desnecessariamente e secrets em variáveis de ambiente. Com poucos ajustes no Dockerfile e docker-compose.yml, você elimina a maioria dos vetores de ataque sem mudar o comportamento da aplicação.
Rodar containers como usuário não-root
Por padrão, processos dentro de containers Docker rodam como root — mesmo que o host tenha proteções, um escape de container com root tem impacto maior:
# Dockerfile — criar e usar usuário não-root
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# Criar usuário não-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Ou em Debian/Ubuntu:
# RUN useradd --create-home --no-log-init appuser
# Dar ownership dos arquivos ao novo usuário
RUN chown -R appuser:appgroup /app
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]
# Verificar que o container não roda como root:
# docker compose exec app id
# uid=1000(appuser) gid=1000(appgroup)Limitar recursos e filesystem read-only
Limite CPU, memória e torne o filesystem do container somente-leitura:
services:
app:
build: .
restart: always
user: "1000:1000" # UID:GID do usuário não-root
# Limitar recursos
deploy:
resources:
limits:
cpus: "1.0" # máximo 1 vCPU
memory: 512M # máximo 512 MB RAM
reservations:
memory: 128M
# Filesystem somente-leitura (exceto volumes explícitos)
read_only: true
tmpfs:
- /tmp # /tmp ainda precisa ser gravável
- /run
# Segurança adicional
security_opt:
- no-new-privileges:true # impedir escalonamento de privilégios
cap_drop:
- ALL # remover todas as capabilities Linux
cap_add:
- NET_BIND_SERVICE # adicionar apenas o necessárioRedes Docker isoladas
Por padrão, todos os containers na mesma rede podem se comunicar. Isole por responsabilidade:
services:
app:
networks:
- frontend_net # acessa o Nginx
- backend_net # acessa o banco
nginx:
networks:
- frontend_net # apenas frontend
postgres:
networks:
- backend_net # apenas backend — sem acesso do Nginx direto
redis:
networks:
- backend_net
networks:
frontend_net:
driver: bridge
backend_net:
driver: bridge
internal: true # sem acesso à internet (apenas comunicação interna)Secrets e variáveis sensíveis
Variáveis de ambiente aparecem em docker inspect. Para secrets críticos, use Docker Secrets (modo Swarm) ou monte arquivos:
# Opção 1: variáveis de ambiente (aceitável, não ideal)
# Aparecem em: docker inspect, /proc/PID/environ
# Mitigação: não expor a porta Docker daemon; usar env_file
# Opção 2: arquivo montado como secret (sem Swarm)
services:
app:
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
volumes:
- /opt/secrets/db_password:/run/secrets/db_password:ro
# Na aplicação Node.js — ler do arquivo:
const dbPassword = process.env.DB_PASSWORD_FILE
? require('fs').readFileSync(process.env.DB_PASSWORD_FILE, 'utf8').trim()
: process.env.DB_PASSWORD
# Opção 3: Docker Secrets (modo Swarm)
# docker secret create db_password /path/to/file
# No compose: secrets: [db_password]Escanear imagens por vulnerabilidades
Use Trivy para detectar CVEs em imagens Docker antes de subir para produção:
# Instalar Trivy (scanner de vulnerabilidades)
apt install -y wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/trivy.list
apt update && apt install trivy
# Escanear imagem local
trivy image minha-api:latest
# Escanear e falhar se houver CVE crítica (bom para CI/CD)
trivy image --exit-code 1 --severity CRITICAL minha-api:latest
# Escanear Dockerfile por má configuração
trivy config ./Dockerfile
# Escanear diretório (IaC)
trivy config ./$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.