# Usando Volumes
O container possui seu próprio sistemas de pastas para organização dos arquivos. Estas pastas, no entanto, não são visíveis para a máquina hospedeira (host). E o pior: quando o container é extinto, os dados que estavam nestas pastas se perdem também. A maneira de preservar os dados é adicionar pastas externas ao container, mapeando-as como se fossem nativas. E para tal usamos os volumes.
Os volumes são versáteis e adiciona novas possibilidades ao ambiente criado por um container:
- Ao excluirmos o container, o volume permanece inalterado, preservando os dados, arquivos de parametros, etc.;
- É possível compartilhar um mesmo volume entre containêres, deixando os dados visíveis para ambos;
- Um volume pode estar localizado em uma outra máquina, na rede local ou em nuvem;
- Um volume pode ser acoplado e desacplado ao container.
TIP
Para situações mais imediatas é possível conectar uma pasta local em um container com o comando -v ou com --mount type=bind
# Conectando uma pasta ao iniciar o container
Para ligar um volume basta usar o parametro v e informar a localização da pasta no servidor, separar por : e informar a pasta no container. As pastas serão criadas, caso não existam e substituídas, caso já exista no container
sudo docker run -v /pasta/pasta_hospedeiro:/pasta_container --name=nome-container -it nome_imagem [comando_container]
Ou para ficar mais legível:
sudo docker run -v /pasta/pasta_hospedeiro:/pasta_container \
--name=nome-container \
-it nome_imagem [comando_container]
Exemplo:
sudo docker run -v /tmp/pasta_hospedeiro:/pasta_container \
--name=alpine_sandbox-06 \
-it alpine /bin/ash
[marcos@localhost ~]$ sudo docker run -v /tmp/pasta_hospedeiro:/pasta_container \
> --name=alpine_sandbox-06 \
> -it alpine /bin/ash
/ # ls
bin etc lib mnt pasta_container root sbin sys usr
dev home media opt proc run srv tmp var
/ # ls -ld /pasta_container
drwxr-xr-x 2 root root 40 Nov 15 10:11 /pasta_container
Verificando em outro terminal:
[marcos@localhost ~]$ ls /tmp
dropbox-antifreeze-ngXrsG ssh-BJo2lg5gQv5v pasta_hospedeiro systemd-private-2d4a70
A partir da versão 17.06 o Docker começou a utilizar o parâmeto --mount que é mais descritivo. E esta sintaxe deve ser adotada. Assim, o comando:
sudo docker run -v /pasta/pasta_hospedeiro:/pasta_container \
--name=nome-container \
-it nome_imagem [comando_container]
Deverá ser substituído por:
sudo docker run --mount type=bind,source=/pasta/pasta_hospedeiro,target=/pasta_container \
--name=nome-container \
-it nome_imagem [comando_container]
Exemplo:
sudo docker run --mount type=bind,source=/home/marcos/docker.images/bind/,target=/pasta_container \
--name=alpine_sandbox-07 \
-it alpine /bin/ash
(executando o container)
marcos@localhost ~]$ sudo docker run --mount type=bind,source=/home/marcos/docker.images/bind/,target=/pasta_container \
> --name=alpine_sandbox-07 \
> -it alpine /bin/ash
/ # ls /pasta_container/
freeplane-icon.png freeplane_logo.jpg
/ #
(verificando na pasta local)
[marcos@localhost ~]$ ls /home/marcos/docker.images/bind/
freeplane-icon.png freeplane_logo.jpg
[marcos@localhost ~]$
WARNING
A ligação de pastas locais ao container, torna-o menos portátil, visto que implica na existencia da mesma estrutura de arquivos na máquina host.
# Objeto Volume
O volume pode ser criado com o compartilhamento de pastas durante a inicialização de um container com a chamada a RUN ou mesmo com o comando VOLUME em um dockerfile. Mas também, pode ser criado sem que esteja associado a qualquer container.
# O comando VOLUME
Para gerenciar a criação de volumes existe o comando volume com os seguintes parâmetros:
Comando | Descrição |
---|---|
create | Cria um volume |
inspect | Lista informações sobre um ou mais volumes |
ls | Lista os volumes criados |
prune | Remove todos os volumes locais não utilizados |
rm | Remove um ou mais volumes |
# Criando um volume
Para criar um volume chamado docker01.vol:
sudo docker volume create nome_volume
Exemplo:
sudo docker volume create docker01.vol
[marcos@localhost ~]$ sudo docker volume create docker01.vol
docker01.vol
# Inspecionando o volume criado
Para ler as iformações referentes ao volume chamado docker01.vol:
sudo docker volume inspect docker01.vol
[marcos@localhost ~]$ sudo docker volume inspect docker01.vol
[
{
"CreatedAt": "2019-11-15T11:02:09-02:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/docker01.vol/_data",
"Name": "docker01.vol",
"Options": {},
"Scope": "local"
}
]
# Listando os volume de um host
Para listar os volumes existentes no servidor:
sudo docker volume ls
[marcos@localhost ~]$ sudo docker volume ls
DRIVER VOLUME NAME
local 226d88056414e07c663082f2cae3010cdb86a635a8fe84e513d645efa49a67b8
local 798f57d1a9f44a6b4c5193921c87a181663c140bad761d2fc8339c0d6dcb1b31
local docker01.vol
local dados_oper.vol
# Removendo volumes
Use o parametro prune para remover todos os volumes que não estão em uso:
sudo docker volume prune
[marcos@localhost ~]$ sudo docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
docker.vol
dados_oper.vol
Total reclaimed space: 0B
[marcos@localhost ~]$
Ou use rm para remover nominalmente um ou mais volumes:
sudo docker volume rm docker02.vol
# Volumes Anexados
# Anexando um volume
Ao criar um container é possível anexar um volume existente:
sudo docker container create --name=nome-container -it --mount source=nome-volume,target=/nome-pasta-container nome-imagem
sudo docker container create --name=volume-sandbox -it --mount source=docker02.vol,target=/meu_volume alpine
marcos@localhost ~]$ sudo docker volume create docker03.vol
docker03.vol
[marcos@localhost ~]$ sudo docker container create --name=volume-sandbox -it --mount source=docker03.vol,target=/meu_volume alpine /bin/ash
e247e0d455f0459a10eb9c3045a6e52ad75468097e2e8b6a96e0c6f8d4d29f39
Inspecionando o container para verficar o volume anexado:
marcos@localhost ~]$ docker container inspect volume-sandbox
... (linhas retiradas)
"Mounts": [
{
"Type": "volume",
"Name": "docker03.vol",
"Source": "/var/lib/docker/volumes/docker03.vol/_data",
"Destination": "/meu_volume",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
...
# Compartilhando arquivos entre contêineres
Para testar o compartilhamento, serão usados dois contêineres (volume-sandbox-01, volume-sandbox-02) e um volume (docker04.vol):
- Criando o volume, os contêineres e iniciando-os:
sudo docker volume create docker04.vol
sudo docker container create --name=volume-sandbox-01 -it \
--mount source=docker04.vol,target=/meu_volume alpine
sudo docker container create --name=volume-sandbox-02 -it \
--mount source=docker04.vol,target=/meu_volume alpine
sudo docker container start volume-sandbox-01
sudo docker container start volume-sandbox-02
- Conectando ao primeiro container. Criando um arquivo texto leiame.txt:
[marcos@localhost ~]$ sudo docker exec -it volume-sandbox-01 /bin/ash
/ # ls
bin dev etc home lib media meu_volume mnt opt proc root run sbin srv sys tmp usr var
/ # cd meu_volume/
/meu_volume # echo "Fui criado a partir de volume-sandbox-01" > leiame.txt
/meu_volume # ls
leiame.txt
- Conectando ao segundo container. Verificando a existência do leiame.txt na pasta meu_volume:
[marcos@localhost ~]$ sudo docker exec -it volume-sandbox-02 /bin/ash
/ # ls
bin dev etc home lib media meu_volume mnt opt proc root run sbin srv sys tmp usr var
/ # cat meu_volume/leiame.txt
Fui criado a partir de volume-sandbox-01
# Copiando arquivos do hospedeiro para o volume
Copiando o arquivo arquivo-do-host.txt do hospdeiro para a pasta meu_volume no container volume-sandbox-01:
`sudo docker container cp arquivo-do-host.txt volume-sandbox-01:/meu_volume`
# Verificando o ponto de montagem do volume criado
sudo docker volume inspect docker04.vol
[marcos@localhost ~]$ sudo docker volume inspect docker04.vol
[
{
"CreatedAt": "2019-11-15T12:36:13-02:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/docker04.vol/_data",
"Name": "docker04.vol",
"Options": {},
"Scope": "local"
}
]
[marcos@localhost ~]$ sudo ls /var/lib/docker/volumes/docker04.vol/_data
arquivo-do-host.txt leiame.txt
Os arquivos arquivo-do-host.txt e leiame.txt estão na pasta _/var/lib/docker/volumes/docker04.vol/data
# Criando Link simbólico para o Ponto de Montagem
O docker possui plugins para permitir que o ponto de montagem seja alterado. Podem ser usados links simbólicos para tornar o acesso aos pontos de montagem mais simples.
- Crie uma pasta para receber os links para seus volumes
sudo mkdir home/marcos/docker.images/volume/
- Crie dentro da mesma, uma pasta com o nome do volume desejado
sudo mkdir /home/marcos/docker.images/volume/docker04.vol
sudo mkdir /home/marcos/docker.images/volume/docker04.vol/dados
Fique Atento
Se já existem arquivos no volume, copie-os para a pasta criada e remova-os do destino!
- Crie o link simbólico
sudo ln -s /home/marcos/docker.images/volume/docker04.vol /var/lib/docker/volumes/docker04.vol/_data
sudo ln -s /home/marcos/docker.images/volume/docker04.vol/dados /var/lib/docker/volumes/docker04.vol/_data
[marcos@localhost ~]$ sudo ln -s /home/marcos/docker.images/volume/docker04.vol/dados /var/lib/docker/volumes/docker04.vol/_data
[marcos@localhost ~]$ sudo docker exec -it volume-sandbox-01 /bin/ash
/ # ls meu_volume/
dados