DOCKER SERIES: LAB … Dados: VOLUMES ( bind, tmpfs, etc )
Falta pouco, caso esteja se perguntando 🙂 Vimos o básico do DOCKER e agora só nos resta alguns tópicos mais avançados. O primeiro será DADOS. Em seguida REDES. E por último COMPOSE (multicontainers).
Abra o seu terminal favorito, e vem comigo!!!
POR QUE as coisas somem?
Leves, práticos, rápidos, e ao mesmo tempo “traiçoeiros”, esses são os containers 🙃 Se você esquecer de salvar as alterações ou, como chamaremos aqui, de persistir os dados … Bem, já era! Tudo foi perdido, literalmente falando. Para que isso não ocorra jamais é necessário usar uma de três técnicas possíveis. São elas: bind mount, tmpfs mount e volume.
Tá Victor, mas ainda não entendi o porquê das informações serem perdidas … Recapitulando, uma imagem nada mais é do que um conjunto de camadas READ-ONLY. Um container é o somatório de uma imagem mais uma camada READ-WRITE. Então, quando eu não persisto essa camada extra em determinado local, a mesma é zerada e completamente refeita na próxima vez que for executada.
Para efeitos de limpeza e ganho de espaço em tela, remova todo(a) e qualquer container/imagem previamente criado(a) ou de laboratórios passados.
sudo service docker start

sudo docker ps -a

sudo docker container rm $(sudo docker container ls -aq)

sudo docker images

sudo docker rmi $(sudo docker images -aq)

QUAL é o tamanho real de um container?
Vamos aprender uma nova flag (parâmetro) para exibir o espaço ocupado por imagens e containers. Basta que você acrescente um -s toda vez que for listá-los. Tal letra vem da palavra SIZE (tamanho, em inglês). Por exemplo:
sudo docker run -it debian bash

(Abra um novo terminal e execute)
sudo docker ps -s

sudo docker history debian

Ok, mas e daí? Perceba que todo container recém-criado tem exatamente o mesmo tamanho da sua imagem base. E por que? Porque até então você não realizou nenhuma operação. Ou seja, não modificou em nada o mesmo. Tudo que está na imagem está contido nele. Por isso o tamanho real é ZERO. Mas, basta apenas qualquer novo comando para tudo mudar e aumentar organicamente. Veja a seguir:
apt-get update

sudo docker ps -s

A-há! Tanto o real quanto o virtual apresentaram valores diferentes e maiores que seus anteriores. Conclusão, a cada operação o espaço do container vai aumentando. E só lembrando que isso se refere aquela camada READ-WRITE “efêmera”. Pois até o momento ainda trata-se de uma área “temporária”.
BIND mounts
Presente desde as primeiras versões do DOCKER, o bind mounts serve para montar determinado arquivo ou pasta do hospedeiro dentro de um container. Na prática pode ser encarado como um vínculo, ligação ou simplesmente um ponteiro. Sempre que quiser trabalhar com este tipo de armazenamento terá que referenciá-lo informando o seu caminho absoluto na máquina hospedeira. Exemplo, /home/user/docker-volume. Apesar do ótimo desempenho e velocidade de acesso muito rápida, os mesmos ainda são altamente dependentes do sistema hospedeiro e suas particularidades. Mais um ponto negativo é o fato de não ser possível usar comandos de Docker CLI para gerenciá-los diretamente.
Enfim, prós e contras à parte, caso essa seja a vossa escolha, vá em frente e crie um novo executando o seguinte:
mkdir docker-volume
sudo docker run -it -v /home/vicrlda/docker-volume:/app debian bash

exit
ls -l /home/vicrlda/docker-volume/

A forma mais semântica, atual e recomendada pela própria documentação oficial é a que segue:
sudo docker run -it --mount type=bind,source=/home/vicrlda/docker-volume,target=/app debian bash
VOLUMES nomeados
Segunda opção da nossa lista, foi batizada simplesmente como VOLUME. E a principal diferença entre ela e sua antecessora (BIND) é o fato de que essa é gerenciada diretamente pelo DOCKER ao invés do SO. Como assim? Lembram que a anterior era performática, mas ainda sim muito dependente do filesystem do hospedeiro? Pois é, aqui isso não acontece. É como se o volume estivesse montado dentro do container e não fora, ou separado (veja a figura 13). Mais adiante veremos que volumes são armazenados em uma pasta específica, reservada para tal fim. E como era de se esperar, tudo isso apresenta certas vantagens. Somente para citar algumas:
- Os volumes são mais fáceis para fazer backup ou migrar
- É possível gerenciá-los usando os comandos da CLI ou API do Docker
- Funcionam em contêineres Linux e Windows
- Podem ser compartilhados com mais segurança entre vários contêineres
- Permitem armazenar volumes em hosts remotos ou provedores de nuvem
- Novos volumes podem ter seu conteúdo preenchido por um contêiner
- Os volumes no Docker Desktop têm um desempenho muito maior do que bind mounts de hosts Mac e Windows

Teoria explicada, vamos à prática. Crie um novo volume executando o seguinte comando:
sudo docker volume create my-volume

sudo docker volume ls

sudo docker run -it -v my-volume:/app debian bash
cd app/
touch new-file.txt
exit

E caso você gere um novo container apontando para o mesmo volume, o arquivo persistirá no mesmo. Observe:
sudo docker run -it -v my-volume:/app ubuntu bash
cd app/
ls -l

Aonde ficam guardados todos esses dados? Nada temam, pois tudo está devidamente salvo na pasta /var/lib/docker/volumes/
sudo su -
cd /var/lib/docker/volumes/
ls

TMPFS mounts
Quando disse aqui que o Linux é o verdadeiro lar do DOCKER, não estava exagerando. Afirmo isso pois certas funcionalidades da nossa querida “Baleia” só irão funcionar no “Pinguim”. É o caso da técnica chamada TMPFS mounts ou montagem tmpfs (em tradução livre). Trata-se de uma pequena área que só é persistida na memória do host, e de forma temporária. Ou seja, quando o container é interrompido, todos os dados são removidos. Tudo isso, é claro, fora da camada READ-WRITE. Para validar: repita o processo de criar um novo container, sair do mesmo, e gerar outro, apontando sempre para a memória.
sudo docker run -it --tmpfs=/app ubuntu bash
ls

Atenção para o detalhe de que agora a pasta app
está igual a tmp
. A cada reinício as informações serão totalmente perdidas. Veja a seguir:
touch app/new-2-file.txt
ls app/
exit
sudo docker run -it --tmpfs=/app ubuntu bash
ls app/

REFERÊNCIAS:
https://docs.docker.com/storage/bind-mounts/