Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 21

Understanding Docker Data Persistence: Volumes, Bind Mounts, and Tmpfs

Recommended resources

Olá! Bem-vindo de volta à nossa jornada pelo Docker.

Na lição anterior, configuramos a comunicação entre contêineres usando redes bridge personalizadas e o DNS interno do Docker. Isso nos permitiu, por exemplo, que uma API .NET se conectasse a um banco de dados PostgreSQL usando o nome do contêiner (Host=my-db). No entanto, deixamos uma questão crítica em aberto: o que acontece com os dados do seu banco de dados se o contêiner my-db for removido? A resposta, por padrão, é que eles são perdidos para sempre.

Nesta lição, vamos resolver esse problema fundamental. Nosso objetivo é explicar a diferença entre volumes, bind mounts e tmpfs mounts para persistência de dados. Ao final, você entenderá por que os contêineres são efêmeros, conhecerá as três principais estratégias para armazenar dados fora de um contêiner e saberá quando usar cada uma delas, uma habilidade essencial para construir aplicações robustas e com estado (stateful).

O Problema: A Natureza Efêmera dos Contêineres

Para entender por que precisamos de armazenamento externo, primeiro precisamos entender como um contêiner armazena dados por padrão. Cada contêiner possui uma "camada de escrita" (writable layer) sobre as camadas somente leitura da imagem.

Free Docker Fundamentals Course - Docker Storage - Writable Layer, Bind Mounts & Volumes

Para começar, vamos visualizar como essa camada de escrita funciona. Este vídeo do canal LearnCantrill oferece uma excelente explicação conceitual do sistema de arquivos em união do Docker.

Assista ao trecho inicial, de 00:00 a 01:55, que explica a camada de escrita e suas implicações. O ponto crucial é que essa camada está diretamente ligada ao ciclo de vida do contêiner.

Como o vídeo explica, qualquer arquivo que você crie ou modifique dentro de um contêiner em execução vai para essa camada de escrita. O problema é que ela é efêmera: quando o contêiner é removido (docker rm), essa camada e todos os seus dados são destruídos com ele.

Isso é inaceitável para a maioria das aplicações do mundo real, como:

  • Bancos de dados: Perder todos os dados de usuários a cada reinicialização é impensável.
  • Logs de aplicação: Logs são cruciais para auditoria e depuração, e precisam sobreviver aos contêineres que os geraram.
  • Uploads de usuários: Arquivos enviados para sua aplicação devem ser armazenados de forma permanente.

A solução é desacoplar os dados do ciclo de vida do contêiner, armazenando-os no sistema de arquivos do host ou em memória. O Docker nos oferece três mecanismos para isso: volumes, bind mounts e tmpfs mounts.


As Três Soluções: Uma Visão Geral

Vamos entender conceitualmente cada uma dessas três opções.

Docker Mount Types for Data Persistence
Este diagrama ilustra a relação entre o contêiner e o host para cada tipo de montagem. O **bind mount** conecta diretamente a um caminho no sistema de arquivos do host. O **volume** usa uma área gerenciada pelo Docker no sistema de arquivos do host. O **tmpfs mount** utiliza a memória do host.

Agora, vamos ler uma visão geral concisa de cada tipo para solidificar esses conceitos.

Docker Mount Types: Volumes, Bind Mounts & tmpfs Guide

O artigo do DataCamp, 'Docker Mount Types', oferece uma excelente seção que resume cada tipo de montagem e seu principal caso de uso.

Leia a seção 'Docker Mount Types at a Glance'. Concentre-se em entender o propósito fundamental de cada um: volumes para produção, bind mounts para desenvolvimento e tmpfs para dados temporários.

Para resumir e comparar, aqui está uma tabela de referência rápida:

Característica Volumes Bind Mounts Tmpfs Mounts
Gerenciamento Gerenciado pelo Docker Gerenciado pelo usuário/host Gerenciado pelo sistema operacional (memória)
Localização Área dedicada no host (/var/lib/docker/volumes/ no Linux) Caminho específico no sistema de arquivos do host Memória RAM do host
Persistência Persistente. Sobrevive à remoção do contêiner. Persistente. Sobrevive à remoção do contêiner. Não persistente. Desaparece quando o contêiner para.
Portabilidade Alta. Não depende da estrutura de diretórios do host. Baixa. Depende de um caminho específico no host. Apenas Linux.
Caso de Uso Principal Dados de produção (bancos de dados, uploads). Desenvolvimento (montar código-fonte para live reload). Dados temporários ou sensíveis (cache, segredos).

Aprofundando em Cada Tipo de Montagem

Agora que temos a visão geral, vamos analisar os detalhes e os casos de uso de cada um, especialmente relevantes para seu trabalho como desenvolvedor.

1. Volumes

Volumes são a maneira recomendada e padrão para persistir dados em produção.

Eles são totalmente gerenciados pelo Docker. Você não precisa se preocupar onde o Docker os armazena no host; você apenas cria um volume nomeado (ex: meu-db-data) e o anexa a um contêiner. Isso os torna portáteis e desacoplados da estrutura de diretórios da máquina host.

Por que usar volumes?

  • Segurança e Isolamento: Previne que um contêiner acesse partes arbitrárias do sistema de arquivos do host.
  • Gerenciamento via CLI: Você pode criar, listar, inspecionar e remover volumes usando comandos docker volume ....
  • Performance: Em Linux, volumes têm performance nativa de disco.
  • Drivers de Volume: Podem ser usados para armazenar dados em provedores de nuvem (como volumes EBS da AWS), o que é crucial para alta disponibilidade.

Day-27 | Docker Volumes and Bind Mounts|Persistent Storage for Docker| #devopstutorialsforbeginners

Para entender as vantagens e o gerenciamento do ciclo de vida dos volumes, este vídeo de Abhishek Veeramalla é muito útil. Ele contrasta volumes com bind mounts e demonstra os comandos.

Assista ao trecho de 11:26 a 17:10. Preste atenção especial às vantagens que ele destaca para os volumes, como o gerenciamento do ciclo de vida e a capacidade de usar armazenamento externo.

2. Bind Mounts

Bind mounts são a ferramenta ideal para ambientes de desenvolvimento.

Eles mapeiam um arquivo ou diretório do seu sistema de arquivos host diretamente para dentro de um contêiner. A principal vantagem é a sincronização em tempo real: qualquer alteração que você fizer no seu código-fonte no seu editor (como VS Code) é refletida instantaneamente dentro do contêiner.

Para você, como desenvolvedor .NET, isso significa que você pode montar o diretório do seu projeto de API em um contêiner e usar o dotnet watch para recompilar e reiniciar sua aplicação automaticamente a cada alteração, sem precisar reconstruir a imagem Docker.

No entanto, eles têm desvantagens que os tornam inadequados para produção:

  • Dependência do Host: O contêiner depende de uma estrutura de diretórios específica no host, quebrando a portabilidade.
  • Risco de Segurança: Um contêiner pode modificar o sistema de arquivos do host, o que é um risco de segurança se o contêiner for comprometido.

Docker Mount Types: Volumes, Bind Mounts & tmpfs Guide

O artigo do DataCamp que lemos anteriormente tem uma excelente seção que detalha o fluxo de trabalho de desenvolvimento com bind mounts, bem como seus riscos.

Leia as seções 'Bind Mounts for Local Development' e 'Docker Mount Performance and Security'. Elas fornecerão o aprofundamento sobre o caso de uso em desenvolvimento e as implicações de segurança e performance que justificam seu uso limitado.

3. Tmpfs Mounts

Tmpfs mounts são para dados que você explicitamente não quer que persistam.

Eles armazenam dados diretamente na memória RAM do host, não no disco. Quando o contêiner é parado, os dados são apagados.

Casos de uso:

  • Dados Sensíveis: Armazenar segredos ou tokens de autenticação temporariamente, garantindo que eles nunca sejam escritos em disco.
  • Cache Temporário: Armazenar dados de cache ou arquivos de estado temporário que não precisam sobreviver a uma reinicialização e se beneficiam da alta velocidade da RAM.

A principal limitação é que os tmpfs mounts só funcionam em hosts Linux.

Test your understanding!

Você está configurando uma aplicação com três serviços em contêineres:

  1. Um banco de dados PostgreSQL.
  2. Uma API .NET que serve o backend.
  3. Um serviço de Redis para cache de sessão.

Para seu ambiente de desenvolvimento local, você quer que as alterações no código-fonte da API sejam refletidas instantaneamente.

Qual tipo de montagem você escolheria para cada um dos seguintes cenários?

  • Para persistir os arquivos do banco de dados PostgreSQL.
  • Para montar o código-fonte da sua API .NET durante o desenvolvimento.
  • Para armazenar os dados do Redis, que não precisam sobreviver a uma reinicialização.
Show answer
  • PostgreSQL: Volume. É a escolha padrão para dados de produção que precisam de persistência, segurança e bom desempenho.
  • API .NET (código-fonte): Bind Mount. Isso permite a sincronização em tempo real entre seu ambiente de desenvolvimento local (seu editor de código) e o contêiner, ideal para live-reloading com dotnet watch.
  • Redis (cache): Tmpfs Mount (se em Linux) seria ideal pela velocidade e porque os dados são voláteis por natureza. Se não for em Linux ou se a persistência temporária for desejável (entre reinicializações de contêiner, mas não necessariamente permanentes), um Volume também poderia ser usado, mas tmpfs é mais adequado para dados verdadeiramente efêmeros.

Conclusão

Hoje, você aprendeu a diferença fundamental entre os três principais mecanismos de armazenamento do Docker. Desacoplar os dados do ciclo de vida do contêiner é um passo crucial para mover de aplicações simples e sem estado para sistemas complexos e robustos.

Principais Pontos:

  • A camada de escrita é efêmera: Dados armazenados diretamente dentro de um contêiner são perdidos quando ele é removido.
  • Volumes para Produção: Use volumes para persistir dados de aplicação como bancos de dados, uploads de usuários e configurações críticas. Eles são gerenciados pelo Docker, portáteis e seguros.
  • Bind Mounts para Desenvolvimento: Use bind mounts para mapear seu código-fonte para dentro de um contêiner, permitindo um fluxo de trabalho de desenvolvimento rápido com live-reloading.
  • Tmpfs Mounts para Dados Temporários: Use tmpfs mounts (em Linux) para dados voláteis ou sensíveis que não devem ser escritos em disco e se beneficiam do acesso rápido à memória.

Com esse conhecimento, você está pronto para não apenas rodar contêineres, mas também gerenciar seus dados de forma eficaz.

Na próxima lição, vamos colocar a mão na massa. Agora que entendemos as diferenças teóricas, vamos nos concentrar no tipo de armazenamento mais importante para produção e criar e gerenciar volumes Docker para persistir os dados de um banco de dados, garantindo que nossas informações estejam seguras, independentemente do que aconteça com o contêiner.