Persistindo dados no Docker: Uma visão geral das opções

Eduardo de Sá
sysvale
Published in
4 min readJun 2, 2023

Quando um contêiner é iniciado no Docker, ele cria uma camada somente de leitura e outra de leitura e gravação na imagem.

Todos os arquivos criados em contêiner são armazenados na camada gravável do contêiner. Isso significa 3 coisas:

  • Os dados não persistem quando o contêiner deixa de existir, e pode ser difícil extrair os dados do contêiner se outro processo precisar deles.
  • A camada gravável de um contêiner está intimamente ligada à máquina host onde o contêiner está sendo executado. Não é fácil mover os dados para outro local.
  • Escrever na camada gravável de um contêiner requer um driver de armazenamento para gerenciar o filesystem. O driver de armazenamento fornece um filesystem de união, usando o kernel do Linux. Essa abstração adicional reduz o desempenho em comparação com o uso de volumes, que escrevem diretamente no filesystem do host.

O Docker nos fornece 2 alternativas para que possamos persistir os dados após o contêiner ser parado: volumes e bind mount.

Vamos ver como utilizar cada uma.

Persistindo dados com bind mount

Primeiramente, vamos precisar criar na sua pasta home, uma pasta chamada volume-docker.

No terminal, verifique se esta no home e crie a pasta com o seguinte comando:

mkdir volume-docker

Ou crie pelo gerenciador de arquivos do seu sistema. Em seguida, rodamos o comando:

docker run -it --mount type=bind,source="/home/<seu-usuario>/volume-docker",target=/app ubuntu bash
  • — mount e type=bind = indicam que vamos fazer um mount do tipo bind
  • target=/app = indica a pasta dentro do contêiner onde iremos salvar os dados
  • source = indica onde os dados serão persistidos
  • ubuntu = é image que usaremos para criar o contêiner
  • bash = vai abrir o shell do container em execução.

Quando o shell do bash abrir iremos executar o comando

cd app/

após essa etapa iremos criar um arquivo executando o comando

touch arquivo-qualquer.txt

Se abrirmos o gerenciador de arquivos e navegarmos até pasta volume-docker, conseguiremos visualizar o arquivo “arquivo-qualquer.txt” que foi criado.

Podemos sair do shell pressionando CTRL + D.

Vamos criar um novo contêiner rodando o seguinte comando:

docker run -it --mount type=bind,source="/home/<seu-usuario>/volume-docker",target=/app ubuntu bash

Agora, vamos para a pasta app

cd /app

Vamos executar em seguida

ls

Veja que o arquivo “arquivo-qualquer.txt” ainda existe, apesar de termos criado um novo contêiner e essa ser uma nova camada gravável. Ainda temos acesso ao arquivo criado. Se não fosse o bind mount, essa informação teria se perdido. Portanto, agora conseguimos persistir informações entre containers. Caso um contêiner pare de funcionar de alguma maneira e queiramos preservar os dados que estejam lá, já conseguimos fazer isso agora.

Persistindo dados com volume:

Quando utilizamos volumes, o próprio Docker vai fazer a gerência do nosso filesystem, o que faz com que ele seja mais confiável de utilizar.

Podemos criar volumes de 2 formas. A primeira é por utilizar o comando:

docker volume create meu-volume

podemos ver o volume criado rodando:

docker volume ls

Para utilizarmos esse volume podemos utilizar o comando:

docker run -it --mount source=meu-volume,target=/app ubuntu bash

Agora ele vai utilizar o meu-volume para armazenar as informações. Entrando no bash dele iremos executar:

cd /app
touch arquivo-qualquer-volume.txt

Após a execução, podemos observar que o arquivo “arquivo-qualquer-volume.txt” não é mais exibido no gerenciador de arquivos como anteriormente. Mas por que isso acontece? Porque nosso source (onde iremos salvar os arquivos) agora é o meu-volume.

Para acessar precisamos rodar os seguintes comando

sudo su
cd /var/lib/docker/volumes/meu-volume/_data

Isso acontece porque agora os arquivos são salvos em uma área do Docker e não no filesystem do dispositivo.

A 2 forma de criar é colocar o nome do novo volume já quando for executar, exemplo:

docker run -it - mount source=meu–novo-volume, target=/app ubuntu bash

Sobre o autor: Eduardo de Sá Lima é desenvolvedor estagiário na Sysvale Softgroup e cursa Licenciatura em Computação no IFSertãoPE.

--

--