Volumes
Volumes são totalmente gerenciados e criados por Docker e você pode criá-los com comandos, ou ainda, Docker pode criar este volume durante a criação do serviço.
.Comando para criar um volume
$ docker volume create <nome do volume>
.Exemplo de como criar um volume e chamá-lo de dados.
$ docker volume create dados
Para listar os volumes.
$ docker volume ls
Com a seguinte saída:
DRIVER VOLUME NAME
local dados
local e8bf838bebbe3576313a6b37a26ab93d1fbb4865174710d9cb4d80366e85c674
Caso não seja específicado nenhum argumento para dar nome ao seu volume, um hash será gerado, conforme exemplo acima onde temos o hash com ínicio e8bf83..
.
Para saber onde foi gerado este diretório com seu volume, é necessário inspecionar este volume.
Para inspecionar um volume utilize o comando inspect
$ docker volume inspect dados`
Com a seguinte saída:
[
{
"CreatedAt": "2019-01-30T14:00:29-02:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/dados/_data",
"Name": "dados",
"Options": {},
"Scope": "local"
}
]
Toda vez que for criado um volume, este volume é guardado em um diretório no Docker host e esta estrutura é que será enviada para dentro do container, mas a grande diferença aqui para bind mounts
é que todo os dados criados neste volume são gerenciados pelo Docker.
Todos os volumes criados podem ser usados por vários containers ao mesmo tempo, ou ainda, quando não houver containers utilizando este volume, ele ficará em espera para quando for preciso utilizá-lo. O importante aqui é que seu volume sempre estará por sua espera para utilizar.
Volumes tem várias vantagens de utilizar do que bind mounts
:
- Fáceis de fazer backups ou fazer migrações.
- É possível gerenciar volumes usando a CLI do Docker ou utilizando a API.
- Volumes funcionam em Linux e Windows.
- Volumes são mais seguros de compartilhar entre vários containers.
- Volumes contêm vários tipos de drivers para trabalhar localmente, provedores de Cloud Computing (AWS, Google Cloud, Azure e outros), para encriptar seu conteúdo ou adicionar funcionalidades.
- Volumes são geralmente uma escolha melhor do que persistir dados na camada de escrita do container, pois o volume não irá aumentar o tamanho do container que o está uando, e o conteúdo do volume é feito totalmente fora de um container.
Para utilizar volumes em linha de comando em Docker, você deve passar o parâmetro -v
. Vejamos um exemplo:
$ docker run \
--rm \
--volume ubuntu-volume:/tmp ubuntu \
mkdir /tmp/novo-diretorio
Com este comando, foi criado um novo diretório em /tmp/novo-diretorio
dentro do container, porém como estamos usando volumes, podemos achar este dado diretamente em nosso host onde persistimos o dado.
Verificando o caminho do volume
$ docker volume inspect ubuntu-volume
Com a seguinte saída.
[
{
"CreatedAt": "2019-01-30T19:40:29-02:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/ubuntu-volume/_data",
"Name": "ubuntu-volume",
"Options": null,
"Scope": "local"
}
]
Com o comando abaixo, verifique se o diretório foi criado.
$ sudo ls -la /var/lib/docker/volumes/ubuntu-volume/_data`
Vamos criar mais dois containers apontando para este mesmo volume, mas, em um destes dois containers, vamos criar alguns arquivos, e no outro container devemos poder listar estes novos arquivos.
$ docker run \
--interactive \
--tty \
--volume ubuntu-volume:/tmp ubuntu
Liste o conteúdo do diretório /tmp
root@a83a59e4555c:/# ls -la /tmp/
total 12
drwxrwxrwt 3 root root 4096 Jan 30 21:40 .
drwxr-xr-x 1 root root 4096 Jan 30 22:07 ..
drwxr-xr-x 2 root root 4096 Jan 30 21:40 novo-diretorio
Abra um novo terminal e rode um novo container, criando alguns arquivos dentro do diretório tmp
.
Criando um novo container
$ docker run \
--interactive \
--tty \
--volume ubuntu-volume:/tmp ubuntu
Criando novos diretórios no diretório /tmp
cd /tmp
root@71df4a42bc32:/tmp# mkdir -p diretorio-a diretorio-b diretorio-c/subdiretorio-a
Liste no primeiro container o diretório tmp
.
root@a83a59e4555c:/# ls -la /tmp/
total 24
drwxrwxrwt 6 root root 4096 Jan 30 22:13 .
drwxr-xr-x 1 root root 4096 Jan 30 22:07 ..
drwxr-xr-x 2 root root 4096 Jan 30 22:13 diretorio-a
drwxr-xr-x 2 root root 4096 Jan 30 22:13 diretorio-b
drwxr-xr-x 3 root root 4096 Jan 30 22:13 diretorio-c
drwxr-xr-x 2 root root 4096 Jan 30 21:40 novo-diretorio
Bind Mounts
Bind mounts são menos eficientes que volumes, pois o diretório ou arquivo que está em sua máquina será apontada para dentro do container. Se estiver iniciando um novo projeto, prefira utilizar volumes no lugar de bind mounts.
Na versão 17.06 do Docker foi introduzido um parâmetro chamado de --mount para containers. Recomenda-se o uso de --mount no lugar do parâmetro -v pois --mount é mais explicito e fácil de utilizar.
Assumindo que você tem um diretório chamado teste e com um arquivo qualquer dentro deste diretório, vamos rodar o comando para montar estes objetos dentro do container.
Para utilizar bind mounts apenas passe este argumento quando chamar um novo container:
$ docker run -it \
--mount type=bind,source=/tmp/teste,target=/tmp/teste \
alpine \
ls -la /tmp/teste
Com a seguinte saída:
total 4
drwxr-xr-x 3 root root 96 Feb 17 00:30 .
drwxrwxrwt 1 root root 4096 Feb 17 00:30 ..
drwxr-xr-x 2 root root 64 Feb 17 00:30 diretorio-a