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!