Pular para o conteúdo

Como persistir dados de contêineres Docker com volumes

Aprenda como usar volumes Docker para preservar dados quando um contêiner é removido e recriado.

Ilustração oficial da documentação do Docker sobre persistência de dados

Docker Docs

O problema dos dados efêmeros

Um contêiner Docker não deve ser confundido com um disco permanente. Quando ele é iniciado, recebe os arquivos e a configuração definidos pela imagem. A aplicação pode criar, alterar e apagar arquivos dentro desse ambiente, mas esses dados acompanham o ciclo de vida do contêiner. Se o contêiner for removido, as alterações feitas apenas na camada interna também deixam de estar disponíveis. Esse comportamento é útil para manter execuções reproduzíveis, mas cria um risco evidente para bancos de dados, uploads, relatórios e qualquer arquivo que precise sobreviver a uma recriação.

A documentação oficial do Docker usa justamente esse contraste para explicar o problema. Reiniciar uma aplicação que guarda dados somente no contêiner pode significar voltar a um estado vazio. Em um teste descartável isso talvez seja aceitável. Em um serviço real, porém, a separação entre processo e dados precisa ser explícita. O contêiner pode ser substituído, atualizado ou removido sem que o armazenamento persistente seja tratado como parte descartável da execução.

Isso também muda a forma de pensar a manutenção. Em vez de copiar arquivos manualmente para dentro de cada contêiner, o administrador define um local persistente e o monta no caminho em que a aplicação grava seus dados. A aplicação continua enxergando um diretório normal, enquanto o Docker mantém os dados fora do ciclo de vida daquele contêiner.

Ilustração oficial da documentação do Docker sobre persistência de dados

Como os volumes funcionam

Volumes são um mecanismo de armazenamento que permite preservar dados além da vida de um contêiner. A ideia é parecida com criar uma ligação entre um caminho dentro do ambiente isolado e uma área administrada pelo Docker. O programa grava no diretório montado, mas os dados continuam disponíveis quando o contêiner é removido e outro contêiner é iniciado usando o mesmo volume.

Essa abordagem reduz o acoplamento entre a aplicação e a instância que a executa. É possível substituir uma imagem, mudar parâmetros de inicialização ou recriar o contêiner sem apagar automaticamente o conteúdo persistente. O volume também pode ser montado por mais de um contêiner quando o caso de uso exige compartilhamento, como em agregação de logs, pipelines de dados ou fluxos orientados a eventos. O compartilhamento, contudo, não elimina a necessidade de coordenar permissões e acesso concorrente.

O volume possui um ciclo de vida próprio. Ele pode continuar existindo depois que o contêiner que o utilizava foi apagado e pode crescer conforme a aplicação grava novos dados. Por isso, persistência não significa armazenamento infinito ou backup automático. O volume precisa ser acompanhado, protegido e incluído na estratégia de recuperação da equipe. A documentação do Docker apresenta volumes como uma forma de manter os dados, não como substituto para cópias de segurança.

Também é importante diferenciar um volume de uma simples alteração na imagem. A imagem fornece a base inicial do contêiner. O volume guarda mudanças que precisam atravessar execuções. Essa separação ajuda a manter a imagem imutável e a deixar o estado mutável em um recurso que pode ser administrado de forma independente.

Montando um volume com docker run

O exemplo apresentado na documentação mostra um volume chamado log-data montado no caminho /logs de um contêiner. A ideia pode ser representada pelo comando docker run -d -p 80:80 -v log-data:/logs docker/welcome-to-docker. A opção -v relaciona o nome do volume ao diretório interno. Se o volume ainda não existir, o Docker pode criá-lo durante a inicialização. A aplicação passa a gravar em /logs, enquanto o volume mantém os arquivos fora do ciclo do contêiner.

O ponto principal do comando não é decorar uma sintaxe isolada. É entender os dois lados do mapeamento: log-data identifica o armazenamento persistente e /logs identifica o local que o processo usa dentro do contêiner. Se o caminho interno não for o mesmo que a aplicação realmente utiliza, o volume existirá, mas não protegerá os arquivos esperados. Antes de executar, confirme na documentação da imagem qual diretório deve ser montado.

Depois de remover o contêiner, a verificação deve criar outro contêiner usando o mesmo volume e o mesmo caminho. Se os arquivos reaparecerem, o teste demonstrou a propriedade que interessa: o dado não dependia da existência da primeira instância. O resultado deve ser conferido lendo o conteúdo, e não apenas verificando se o comando terminou sem erro.

Para evitar confusão, use nomes de volume que indiquem o serviço ou o ambiente. Em projetos maiores, registre também quem é responsável pelo volume, qual aplicação o utiliza, qual é o caminho de montagem e qual política de retenção deve ser aplicada. A clareza do nome não altera o comportamento técnico, mas reduz o risco de apagar o recurso errado durante uma manutenção.

Ilustração oficial da documentação do Docker sobre dados persistentes em volumes Docker

Testando a persistência com PostgreSQL

O tutorial oficial usa um contêiner PostgreSQL para tornar o teste observável. A execução cria um volume chamado postgres_data e o monta em /var/lib/postgresql, que é o diretório usado pelo banco no exemplo. A inicialização também configura a senha e associa o volume ao contêiner. O objetivo é inserir registros, remover a primeira instância e iniciar uma nova usando o mesmo volume.

Em seguida, o leitor entra no PostgreSQL, cria uma tabela e insere dois registros. Essa etapa é importante porque produz um estado que pode ser comparado depois. Não basta ver o banco iniciar novamente: é preciso consultar a tabela e confirmar que os mesmos dados continuam presentes. O tutorial também destaca que a variável usada para configurar a senha só participa da inicialização de um banco novo. Quando o diretório já contém dados persistidos, a aplicação pode seguir um caminho diferente.

O teste fica completo quando o primeiro contêiner é parado e removido, e um novo contêiner é iniciado com o volume postgres_data montado no mesmo caminho. A nova instância deve encontrar os arquivos do banco e retornar os registros criados anteriormente. Se o caminho, o nome do volume ou a configuração da aplicação mudar, a comparação deixa de ser válida. Por isso, registre exatamente o comando utilizado e faça a leitura de volta dentro da nova instância.

Esse experimento também mostra por que uma atualização de imagem não deve ser tratada como uma atualização dos dados. A imagem pode mudar, enquanto o volume continua representando o estado da aplicação. Ainda assim, versões diferentes podem exigir migrações ou formatos compatíveis. Persistir o diretório evita a perda acidental, mas não garante que qualquer versão consiga interpretar os arquivos sem preparação.

Como compartilhar dados e administrar volumes

Um volume pode ser montado em mais de um contêiner quando o fluxo precisa compartilhar arquivos. A documentação cita possibilidades como agregação de logs, pipelines de dados e aplicações orientadas a eventos. O desenho deve considerar se os processos realmente podem acessar os mesmos arquivos e como conflitos serão tratados. Compartilhar um volume não é o mesmo que oferecer uma API de dados; dois processos escrevendo no mesmo arquivo ainda podem corromper o conteúdo se não houver coordenação.

Os volumes podem crescer bastante, especialmente quando guardam bancos, logs ou artefatos de processamento. A administração precisa acompanhar o consumo de espaço e definir quando um recurso pode ser arquivado ou removido. O Docker Desktop oferece recursos para visualizar conteúdo, exportar, importar, esvaziar, apagar e clonar volumes. Essas ações são úteis, mas devem ser executadas com atenção ao vínculo entre o volume e os contêineres que ainda o utilizam.

Antes de remover um volume, confirme que ele não está anexado a contêineres importantes. A documentação ressalta que a remoção depende desse vínculo. Em operações de produção, prefira uma sequência que pare a aplicação, confirme o backup, registre o estado e só então altere o armazenamento. Uma interface que permite excluir um volume torna a ação acessível, não necessariamente reversível.

Para fechar o ciclo, mantenha a fonte original por perto e revise o procedimento quando a versão do Docker, da imagem ou do banco mudar. Este tutorial foi baseado na documentação oficial disponível em https://docs.docker.com/get-started/docker-concepts/running-containers/persisting-container-data. A referência explica os comandos e os caminhos usados no exemplo, enquanto o ambiente de cada projeto pode exigir ajustes de permissões, credenciais e políticas de retenção.

Resumo da semana

Leve contexto para a caixa de entrada.

Uma edição semanal, sem barulho e sem promessas vazias.