Docker/Artigo

    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:

    bash
    # 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"
    Dica
    Imagens oficiais modernas (node:alpine, python:slim, nginx:alpine) já têm usuários não-root pré-configurados. Verifique a documentação da imagem antes de criar o seu próprio.

    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:

    bash
    # 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 diretamente
    Atenção
    Um container com acesso ao Docker socket pode criar novos containers com --privileged, montar qualquer volume do host e executar comandos como root no host. Isso é escalada de privilégio completa.

    Filesystem read-only e capabilities

    Containers com filesystem somente leitura e capabilities reduzidas têm superfície de ataque muito menor:

    yaml
    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ário
    Dica
    cap_drop: ALL + cap_add apenas do necessário segue o princípio do menor privilégio. Aplicações web típicas precisam de no máximo NET_BIND_SERVICE (para portas < 1024) — na maioria dos casos, nenhuma capability extra é necessária se você usa portas > 1024.

    Limitar 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:

    yaml
    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 container

    Usar imagens verificadas e atualizadas

    Imagens desatualizadas contêm vulnerabilidades conhecidas. Práticas para manter imagens seguras:

    bash
    # 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
    Dica
    Imagens :alpine são baseadas no Alpine Linux (5 MB base) — muito menores que :debian. Menos pacotes = menos vulnerabilidades. A desvantagem é que usam musl libc em vez de glibc, o que pode causar incompatibilidades com alguns binários.

    $ 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.

    Perguntas frequentes