Tipos de Volumes no Docker
Tags: docker, volume
Published: 2021-09-04 15:49:00

## 1. Para que serve o volume no Docker ?  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tknbdi0780vjbch9o0a.png)
Basicamente utilizamos o volume para fazer a persistência de dados entre nossa máquina e o container.  

## 2. Tipos de Volume  
* Bind-mount
* Volume / Volume Nomeado
* Volume Temporário  

## 3. Bind-mount  
* Exemplo de uso  
```
docker run -it \
-v /home/devlmoreno/docker-volumes/my-folder-bind:/my-app-docker \
ubuntu:20.04  
```  
* Para exemplificar o uso, começamos criando um diretório em nosso sistema com o nome *'my-folder-bind'*, logo em seguida criamos o container.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmjc9k1aueduj1qriya0.png)  
* Por fim criamos um arquivo (*bind-mount.txt*) em nosso sistema (podendo ser a criação do arquivo dentro do container também). Pode-se observar que o arquivo é exibido normalmente tanto dentro do container quanto em nosso sistema.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wn4v6we9qghx9peqvrnu.png)    
* Esse tipo de Volume não é um volume criado pelo próprio Docker, ou seja, fazemos uma referência do caminho absoluto do nosso sistema para o diretório 'my-app-docker' dentro do nosso container.  

## 4. Volume  (Gerenciado pelo Docker)  
* Exemplo de uso  
```
docker run -it \
-v /my-app-docker \
ubuntu:20.04  
```
* Nesse caso, o Docker cria um volume automaticamente dentro do nosso sistema e faz essa referência para o diretório 'my-app-docker' dentro do nosso container.  

##### Para exemplificar o uso

1. Criamos o container.
  * ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yuysvp4aai0buu3ojhw.png)
2. Executamos o comando **docker inspect id_container** para inspecionarmos as configurações do nosso container . 
  * `docker inspect 1ba5ab5ab9e0`
3. Procuramos pelo atributo **Mounts** e em seguida o **Source** para descobrirmos o caminho do diretório que o Docker criou em nosso sistema para gerenciar o volume.
  * ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bb40bh314p12e15371oh.png)
4. Copiamos o caminho do diretório e logamos como **sudo** (por conta do caminho ser protegido), logo em seguida acessamos o diretório.
  * Por eu estar utilizando o **wsl2 (ambiente linux dentro do windows)** para exemplificar esse tipo de volume, o caminho do volume criado pelo Docker fica em um caminho diferente do que é listado no **Mounts > Source**, caso você não esteja utilizando o **wsl2** basta acessar o caminho exibido no **Mounts > Source** normalmente.  
  * **Exemplo do caminho com wsl2**
      * `cd \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes`
      * `cd 1ba0860040f23624cb8efbbfde2f53af0b1d00c4af9d588299427b096ac17696`
      * `cd .\_data\`
  * **Exemplo do caminho para ambientes linux comuns**
      * `cd/var/lib/docker/volumes/7e5cc9339921d493553691db46fceed61f89d9cc60abf6b2c1060811166a0c4d/_data`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qu0iqnho3o80vlcmxwk.png)
5. Criamos um arquivo dentro do diretório do nosso sistema e listamos esse arquivo no container.
  * `echo "Volume Gerenciado pelo Docker!" > volume-gerenciado-docker.txt`
  * Para criar um arquivo no linux basta digitar `touch arquivo.txt`. No exemplo acima o arquivo foi criado a partir do powershell do windows por conta da utilização do wsl2.

## 5. Diferença entre Bind-mount e Volume  
O **Bind-mount** faz uma referência a um **caminho absoluto** do nosso sistema, ou seja, nos permite escolher qual diretório queremos mapear ao docker, por conta disso ficamos "reféns" da estrutura de diretórios.
No formato Volume, o Docker faz esse trabalho, com isso abrimos um leque de possibilidades para utilizarmos os comandos que o mesmo disponibiliza, como por exemplo, create, inspect, rm, prune e etc.

## 6. Volume Nomeado (Gerenciado pelo Docker)
* Exemplo de uso  
```
docker run -it \
-v my-volume-docker:/my-app-docker \
ubuntu:20.04
```  
* Crie um volume através do comando do Docker.  
  * `docker volume create my-volume-docker`  
* Execute o container através do comando do exemplo de uso.  
* Para encontrar seu volume nomeado que foi criado (my-volume-docker) acesse o diretório `/var/lib/docker/volumes`, caso esteja utilizando o **wsl2** seu volume será encontrado no diretório `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes`.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6qp63y3upc19wy9wk6z.png)
* Em seguida crie um arquivo dentro desse diretório e faça a listagem do mesmo no seu container, pronto, seu arquivo estará lá para ser acessado.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shrdtol5xrmlcwmwepys.png)

## 7. Volume Temporário (Esse tipo de volume funciona apenas no Linux)  
* Exemplo de uso
```
docker run -it \
--tmpfs /my-app-docker \
ubuntu:20.04
```
* Enquanto nosso container estiver sendo executado, esse volume estará sendo armazenado na nossa **memória RAM**, ou seja, será um acesso mais **rápido** ao volume porém **volátil**, **não teremos uma persistência de dados** envolvida nesse método.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2zx2kdk1hfz4b6wb78b.png)

## 8. Recomendações Docker
* Por conta de facilitar o entendimento na hora da leitura do comando, é recomendando pelo próprio Docker utilizar a flag **--mount** ao invés da flag **-v**.
* Exemplo do comando com a flag **--mount**  
```
docker run -it \
--mount type=bind,source=/home/devlmoreno/docker-volumes/my-folder-bind,target=/my-app-docker \
ubuntu:20.04
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxztfmvb1m0ngv3lmwxd.png)  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xd4zhsx1dkod0zb9m12l.png)  
* Estrutura do comando com a flag.
  * type = **bind** | **volume (default)** | **tmpfs**  
  * source = **diretório do nosso sistema**  
  * target = **diretório dentro do container**  
* No caso do type tmpfs, **não teríamos um source**, basta retirar esse parâmetro do comando.
```
docker run -it \
--mount type=tmpfs,target=/my-app-docker \
ubuntu:20.04
```  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9sxm5xia4t11c4o1g7z.png)  
* No caso de um volume nomeado, seguindo nosso exemplo anterior e assumindo que você criou o volume a partir do gerenciamento do Docker, podemos utilizar o comando dessa forma.
```
docker run -it \
--mount source=my-volume-docker,target=/my-app-docker \
ubuntu:20.04
```
  * Nota-se que no comando nós não passado o type, isso por conta do valor **default** do type ser **volume**.  

## 9. Documentação Docker sobre Volumes
* https://docs.docker.com/storage/