Data volumes are specially-designated directories, within one or more containers that bypasses the Union File System(UnionFS).
Let’s create a container with a mounted volume called my_volume
$ docker run -itd --name volume_test_1 -v /my_volume ubuntu:14.04
Just like for networks, we can inspect the mounted volume both from the container and the server side
$ docker inspect volume_test_1
...
"Mounts": [
{
"Name": "b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531",
"Source": "/mnt/sda1/var/lib/docker/volumes/b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531/_data",
"Destination": "/my_volume",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
$ docker volume ls
DRIVER VOLUME NAME
local b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531
$ docker volume inspect b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531
[
{
"Name": "b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531",
"Driver": "local",
"Mountpoint": "/mnt/sda1/var/lib/docker/volumes/b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531/_data"
}
]<
The name my_volume that we have given, is a local name for the mountpoint within the container. This is why it does not appear in the volume list when we inspect the volumes of the docker server. In other words we can have the same name for mountpoints in different containers, with the corresponding volumes having nothing in common.
Let’s show that with an example. We will create another container with the same volume name
$ docker run -itd --name volume_test_2 -v /my_volume ubuntu:14.04
121357b918817c3f5e1fd02344f7fa19ec587a7c32c0c2719636939a2a591508
Now, inspect the volumes and you’ll see that there is another volume created
$ docker volume ls
DRIVER VOLUME NAME
local b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531
local 097f4e2e291a851b5282bd0ac6460f3e162ca047ed155d10b22c05b321853d72
The two volumes are totally different. If we attach to one of the containers and make a change in its my_volume, the change will not be visible from the other container
$ docker attach volume_test_2
root@121357b91881:/#
root@121357b91881:/# cd /my_volume/
root@121357b91881:/my_volume# touch my_test_file
root@121357b91881:/my_volume# ls -al
total 8
drwxr-xr-x 2 root root 4096 Jul 14 11:54 .
drwxr-xr-x 34 root root 4096 Jul 14 11:23 ..
-rw-r--r-- 1 root root 0 Jul 14 11:54 my_test_file
$ docker attach volume_test_1
root@7712450e10e2:/#
root@7712450e10e2:/# ls -al /my_volume/
total 8
drwxr-xr-x 2 root root 4096 Jul 14 11:18 .
drwxr-xr-x 34 root root 4096 Jul 14 11:18 ..
Let’s delete these volumes and try a couple of other things
$ docker volume ls
DRIVER VOLUME NAME
local 097f4e2e291a851b5282bd0ac6460f3e162ca047ed155d10b22c05b321853d72
local b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531
$ docker volume rm 097f4e2e291a851b5282bd0ac6460f3e162ca047ed155d10b22c05b321853d72
Error response from daemon: Unable to remove volume, volume still in use: remove 097f4e2e291a851b5282bd0ac6460f3e162ca047ed155d10b22c05b321853d72: volume is in use - [121357b918817c3f5e1fd02344f7fa19ec587a7c32c0c2719636939a2a591508]
We have hit a wall because the volume is still in use. It is a general rule with Docker containers that no object can be deleted if it is a dependency of another object, i.e. it is used by another object.
Therefore before we delete the volume we have to delete (not just stop) the container that is using it. Let’s delete both of the pairs of containers and volumes we have created for this test and get over with it.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
121357b91881 ubuntu:14.04 "/bin/bash" 46 minutes ago Up 33 minutes volume_test_2
7712450e10e2 ubuntu:14.04 "/bin/bash" 51 minutes ago Up 38 minutes volume_test_1
$ docker stop volume_test_1 volume_test_2
volume_test_1
volume_test_2
$ docker volume rm 097f4e2e291a851b5282bd0ac6460f3e162ca047ed155d10b22c05b321853d72 b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531
097f4e2e291a851b5282bd0ac6460f3e162ca047ed155d10b22c05b321853d72
b5a0022b4bed22797737f72f771b1b57758bd394d22e1332170b8c8a6407c531
We have seen that it is a bit awkward to use the hex signatures that docker is assigning as volumes names. Combined with the fact that I have forgotten to mention this before, here is the way to name a volume any way you like
$ docker run -itd --name volume_test_1 -v my_volume_name_1:/my_volume ubuntu:14.04
5be6fe9cad15072d0734d7070cf3ce3087067330d89af9588fff2b36162a186c
$ docker run -itd --name volume_test_2 -v my_volume_name_2:/my_volume ubuntu:14.04
b5a97e845ad3220ecd4cea2068b168253275c644b9be2a0e4393e055f25a3936
$ docker volume ls
DRIVER VOLUME NAME
local my_volume_name_1
local my_volume_name_2
Much better.
Last but not least, since as we said the volume is an entity that bypasses the UnionFS, we can create volumes without mounting them to containers
$ docker volume create --name yet_another_volume
yet_another_volume
$ docker volume ls
DRIVER VOLUME NAME
local yet_another_volume
Since this is a volume that exists beyond containers, we can mount it to as many containers as we like. In fact, we can mount it under different mount points inside each container and still all containers will refer to the same volume
$ docker run -itd --name shared_volume_test1 -v yet_another_volume:/volume1 ubuntu:14.04
5bb2f4995e87fe4e114b63067be29a4c2f94f2ae54a1ed314c1db6d6b210962f
$ docker run -itd --name shared_volume_test2 -v yet_another_volume:/volume2 ubuntu:14.04
066230ac2c6ea46b5aa366a376d91e7be2a037105e3a5902ef9514c6716b7e5a
Now, make a change in the new volume in one of the containers and try to see it from the other
$ docker attach shared_volume_test1
root@5bb2f4995e87:/# cd /volume1/
root@5bb2f4995e87:/volume1# touch test_file
root@5bb2f4995e87:/volume1# ls
test_file
<CTRL-P> <CTRL-Q>
$ docker attach shared_volume_test2
root@066230ac2c6e:/# cd /volume2/
root@066230ac2c6e:/volume2# ls
test_file
That was it. Thanks for coming here!