Docker/Artigo

    Docker volumes: como persistir dados de containers

    Por padrão, dados escritos dentro de um container são perdidos quando ele é removido. Para persistir dados — banco de dados, uploads, configs — você precisa de volumes. Volumes nomeados (managed pelo Docker) são a escolha certa para dados de aplicação como PostgreSQL e Redis. Bind mounts (diretório do host montado no container) são ideais para arquivos de configuração e código em desenvolvimento.

    Volumes nomeados vs bind mounts

    Os dois tipos de montagem têm usos distintos:

    Dica
    Volume nomeado: gerenciado pelo Docker, armazenado em /var/lib/docker/volumes/. Portável, backup simples, permissões gerenciadas. Use para dados de banco de dados, uploads de usuários, state da aplicação. Bind mount: diretório do host montado diretamente. Você controla o path, arquivos ficam visíveis no host. Use para arquivos de configuração, código em desenvolvimento, logs que você quer acessar diretamente. Tmpfs mount: memória volátil. Use para dados sensíveis temporários (tokens, sessões) que não devem chegar ao disco.

    Volumes no docker-compose.yml

    Declaração correta de volumes nomeados no Compose — note que a seção volumes: no topo nível é obrigatória:

    yaml
    services:
      postgres:
        image: postgres:16
        volumes:
          - pg_data:/var/lib/postgresql/data   # volume nomeado
    
      nginx:
        image: nginx:alpine
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf:ro  # bind mount (read-only)
          - ./html:/usr/share/nginx/html           # bind mount (leitura e escrita)
    
      app:
        image: minha-app:latest
        volumes:
          - uploads:/app/uploads               # volume nomeado para uploads
    
    # Declara os volumes nomeados
    volumes:
      pg_data:
      uploads:
    Dica
    O sufixo :ro (read-only) impede o container de modificar o arquivo — use para arquivos de configuração onde você não quer que o container altere acidentalmente.

    Inspecionar e gerenciar volumes

    Comandos essenciais para trabalhar com volumes:

    bash
    # Listar todos os volumes
    docker volume ls
    
    # Ver detalhes de um volume (onde está no disco, quem usa)
    docker volume inspect pg_data
    
    # Ver qual container está usando o volume
    docker ps --filter volume=pg_data
    
    # Remover volumes não utilizados (cuidado — irrecuperável)
    docker volume prune
    
    # Remover um volume específico (container deve estar parado)
    docker volume rm nome_do_volume
    Atenção
    docker volume prune e docker volume rm são irreversíveis — não há lixeira. Faça backup antes de remover qualquer volume com dados de produção.

    Backup de volumes

    O método mais portável para backup de volumes Docker é criar um container auxiliar para comprimir os dados:

    bash
    # Backup de um volume para arquivo tar.gz no diretório atual
    docker run --rm   -v pg_data:/source:ro   -v $(pwd):/backup   alpine tar czf /backup/pg_data-backup-$(date +%Y%m%d).tar.gz -C /source .
    
    # Restaurar de um backup
    docker run --rm   -v pg_data:/target   -v $(pwd):/backup   alpine tar xzf /backup/pg_data-backup-20260607.tar.gz -C /target
    Dica
    Para PostgreSQL, prefira pg_dump em vez de backup de arquivo — garante consistência. docker exec postgres pg_dump -U usuario nome_db > backup.sql. Backups de arquivo raw funcionam melhor com o container parado.

    Permissões em volumes

    Um problema comum: o processo dentro do container tenta escrever no volume mas não tem permissão. Acontece quando o UID do processo no container não bate com o dono do diretório no host:

    bash
    # Ver o UID do processo dentro do container
    docker exec nome_container id
    
    # Ajustar dono do diretório de bind mount para o UID correto
    # (ex: UID 1000 para aplicações Node.js não-root)
    chown -R 1000:1000 ./dados
    
    # Ou inicializar o volume com as permissões corretas
    docker run --rm -v meu_volume:/data alpine chown -R 1000:1000 /data
    Dica
    Imagens bem construídas (Node.js oficial, nginx) já rodam como usuário não-root com UID conhecido. Consulte a documentação da imagem para saber qual UID usar.

    $ 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