• Volumes are used to decouple data from containers
  • Its also a mechanism to share data between containers

Creating a mount point within a container and storing any data written to that location outside of the containers union file system, i.e. store the data into the directory of the docker host file system, which is an outstanding feature because even when the containers are either stopped or crashed the data is still persisted into host file system and hence is accessible in next container run.

Docker mounting volume using docker run

root@ubuntu14-04:/home/kmaringanti#
root@ubuntu14-04:/home/kmaringanti# docker run -it -v /voldata ubuntu:16.10 /bin/bash
root@ce9ef9fdd9eb:/#

The /voldata directory actually doesn’t exist in host, but if it does then normal unix mount rules apply. That is any data already exists in the mount point becomes unavailable while there’s a volume mounted in it.


root@ubuntu14-04:/home/kmaringanti#
root@ubuntu14-04:/home/kmaringanti# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ce9ef9fdd9eb        ubuntu:16.10        "/bin/bash"         9 seconds ago       Up 9 seconds                            angry_feynman

Check the process listing


root@ubuntu14-04:/home/kmaringanti# docker attach angry_feynman

root@ce9ef9fdd9eb:/#
root@ce9ef9fdd9eb:/# ls -l
total 68
drwxr-xr-x   2 root root 4096 Nov  4 20:31 bin
drwxr-xr-x   2 root root 4096 Oct  8 10:11 boot
drwxr-xr-x   5 root root  380 Nov 30 12:30 dev
drwxr-xr-x  35 root root 4096 Nov 30 12:30 etc
drwxr-xr-x   2 root root 4096 Oct  8 10:11 home
drwxr-xr-x   8 root root 4096 Nov  4 20:31 lib
drwxr-xr-x   2 root root 4096 Nov  4 20:30 lib64
drwxr-xr-x   2 root root 4096 Nov  4 20:30 media
drwxr-xr-x   2 root root 4096 Nov  4 20:30 mnt
drwxr-xr-x   2 root root 4096 Nov  4 20:30 opt
dr-xr-xr-x 126 root root    0 Nov 30 12:30 proc
drwx------   2 root root 4096 Nov  4 20:31 root
drwxr-xr-x   5 root root 4096 Nov 16 20:58 run
drwxr-xr-x   2 root root 4096 Nov 16 20:58 sbin
drwxr-xr-x   2 root root 4096 Nov  4 20:30 srv
dr-xr-xr-x  13 root root    0 Nov 30 09:08 sys
drwxrwxrwt   2 root root 4096 Nov  4 20:31 tmp
drwxr-xr-x  11 root root 4096 Nov 16 20:58 usr
drwxr-xr-x  13 root root 4096 Nov 16 20:58 var
drwxr-xr-x   2 root root 4096 Nov 30 12:30 voldata

check the voldata folder got created


root@ce9ef9fdd9eb:/voldata# cat >sample.txt
entering sample text into sample file
^C
root@ce9ef9fdd9eb:/voldata#


root@ce9ef9fdd9eb:/voldata# cat sample.txt
entering sample text into sample file
root@ce9ef9fdd9eb:/voldata#

Create a sample file in that volume


root@ubuntu14-04:/home/kmaringanti# docker inspect angry_feynman
[{
    "AppArmorProfile": "",
    "Args": [],
    "Config": {
        "AttachStderr": true,
        "AttachStdin": true,
        "AttachStdout": true,
...
...
        "StartedAt": "2016-11-30T12:30:26.474382393Z"
    },
    "Volumes": {
        "/voldata": "/var/lib/docker/vfs/dir/2604471c3e19e5b7a22d888aba946d9e3aead1da7d42d3444730df5ba4d5a6c6"
    },
    "VolumesRW": {
        "/voldata": true
    }
}
]

Inspect and find the volumes section where you find the same voldata created which is mapped to a folder in docker host.


root@ubuntu14-04:/home/kmaringanti# cat /var/lib/docker/vfs/dir/2604471c3e19e5b7a22d888aba946d9e3aead1da7d42d3444730df5ba4d5a6c6/sample.txt
entering sample text into sample file
root@ubuntu14-04:/home/kmaringanti#

Now check the contents of the file created and will be the same and got saved in the Dcoker host.


Running another container sharing the volume

root@ubuntu14-04:/home/kmaringanti# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ce9ef9fdd9eb        ubuntu:16.10        "/bin/bash"         13 minutes ago      Up 13 minutes                           angry_feynman
     
root@ubuntu14-04:/home/kmaringanti# docker run -it --name="volcontainer2" --volumes-from="angry_feynman" ubuntu:16.10 /bin/bash
root@a7a8c38b1a9e:/#

Create another container by liking the same volumes used by the previously created angry_feynman container.


root@a7a8c38b1a9e:/#
root@a7a8c38b1a9e:/# ls -l
total 68
drwxr-xr-x   2 root root 4096 Nov  4 20:31 bin
drwxr-xr-x   2 root root 4096 Oct  8 10:11 boot
drwxr-xr-x   5 root root  380 Nov 30 12:44 dev
drwxr-xr-x  35 root root 4096 Nov 30 12:44 etc
drwxr-xr-x   2 root root 4096 Oct  8 10:11 home
drwxr-xr-x   8 root root 4096 Nov  4 20:31 lib
drwxr-xr-x   2 root root 4096 Nov  4 20:30 lib64
drwxr-xr-x   2 root root 4096 Nov  4 20:30 media
drwxr-xr-x   2 root root 4096 Nov  4 20:30 mnt
drwxr-xr-x   2 root root 4096 Nov  4 20:30 opt
dr-xr-xr-x 130 root root    0 Nov 30 12:44 proc
drwx------   2 root root 4096 Nov  4 20:31 root
drwxr-xr-x   5 root root 4096 Nov 16 20:58 run
drwxr-xr-x   2 root root 4096 Nov 16 20:58 sbin
drwxr-xr-x   2 root root 4096 Nov  4 20:30 srv
dr-xr-xr-x  13 root root    0 Nov 30 09:08 sys
drwxrwxrwt   2 root root 4096 Nov  4 20:31 tmp
drwxr-xr-x  11 root root 4096 Nov 16 20:58 usr
drwxr-xr-x  13 root root 4096 Nov 16 20:58 var
drwxr-xr-x   2 root root 4096 Nov 30 12:31 voldata
root@a7a8c38b1a9e:/#
root@a7a8c38b1a9e:/#

Here the same volume is mounted.


root@a7a8c38b1a9e:/#
root@a7a8c38b1a9e:/# cat voldata/sample.txt
entering sample text into sample file
root@a7a8c38b1a9e:/#

Check the contents of the file and will find the same as created earlier using the previously created container. This proves that the volume is shared.


Docker mounting from docker host file system

Here we try mount an already created folder in host into the docker.

root@ubuntu14-04:/home/kmaringanti#
root@ubuntu14-04:/home/kmaringanti# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a7a8c38b1a9e        ubuntu:16.10        "/bin/bash"         5 minutes ago       Up 5 minutes                            volcontainer2     
ce9ef9fdd9eb        ubuntu:16.10        "/bin/bash"         19 minutes ago      Up 19 minutes                           angry_feynman     
root@ubuntu14-04:/home/kmaringanti#

For now we have two containers.


root@ubuntu14-04:/home/kmaringanti#
root@ubuntu14-04:/home/kmaringanti# mkdir /volinhost
root@ubuntu14-04:/home/kmaringanti#
root@ubuntu14-04:/home/kmaringanti#

Create a folder in host volinhost.


root@ubuntu14-04:/home/kmaringanti# docker run -it --name="volcontainer3" -v /volinhost:/volindocker ubuntu:16.10 /bin/bash
root@f315c23c1f59:/#
root@f315c23c1f59:/#
root@f315c23c1f59:/# ls -l
total 68
drwxr-xr-x   2 root root 4096 Nov  4 20:31 bin
drwxr-xr-x   2 root root 4096 Oct  8 10:11 boot
drwxr-xr-x   5 root root  380 Nov 30 12:52 dev
drwxr-xr-x  35 root root 4096 Nov 30 12:52 etc
drwxr-xr-x   2 root root 4096 Oct  8 10:11 home
drwxr-xr-x   8 root root 4096 Nov  4 20:31 lib
drwxr-xr-x   2 root root 4096 Nov  4 20:30 lib64
drwxr-xr-x   2 root root 4096 Nov  4 20:30 media
drwxr-xr-x   2 root root 4096 Nov  4 20:30 mnt
drwxr-xr-x   2 root root 4096 Nov  4 20:30 opt
dr-xr-xr-x 130 root root    0 Nov 30 12:52 proc
drwx------   2 root root 4096 Nov  4 20:31 root
drwxr-xr-x   5 root root 4096 Nov 16 20:58 run
drwxr-xr-x   2 root root 4096 Nov 16 20:58 sbin
drwxr-xr-x   2 root root 4096 Nov  4 20:30 srv
dr-xr-xr-x  13 root root    0 Nov 30 09:08 sys
drwxrwxrwt   2 root root 4096 Nov  4 20:31 tmp
drwxr-xr-x  11 root root 4096 Nov 16 20:58 usr
drwxr-xr-x  13 root root 4096 Nov 16 20:58 var
drwxr-xr-x   2 root root 4096 Nov 30 12:52 volindocker
root@f315c23c1f59:/#
root@f315c23c1f59:/#

Now spin a new container volcontainer3 by mapping the volume of host to volume in docker -v /volinhost:/volindocker. Once created, check using ls -l and you will see the one got mounted.


root@f315c23c1f59:/# cd volindocker/
root@f315c23c1f59:/volindocker#
root@f315c23c1f59:/volindocker# cat >hello.txt
this is hello text file
^C
root@f315c23c1f59:/volindocker#
root@f315c23c1f59:/volindocker#

Create a file hello.txt with some contents.


root@ubuntu14-04:/home/kmaringanti#
root@ubuntu14-04:/home/kmaringanti# cat /volinhost/hello.txt
this is hello text file
root@ubuntu14-04:/home/kmaringanti#
root@ubuntu14-04:/home/kmaringanti#

Come out of the docker container by issuing command CTRL + P + Q and check the volinhost folder and you will see the file with contents.


NOTE: This approach is not scalable since the containers which are spun in the host are tied to the same folder in the same host. And due to this tight coupling, usage of Dockerfile as mentioned in below approach is recommended.

Create Volumes using Dockerfile

Below are contents of the Dockerfile


root@ubuntu14-04:/home/kmaringanti/voltest# cat Dockerfile
	
FROM ubuntu:16.10

VOLUME /data

CMD ["/bin/bash"]


root@ubuntu14-04:/home/kmaringanti/voltest# docker build -t=voltest .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:16.10
 ---> 241684c864ba
Step 1 : VOLUME /data
 ---> Running in 830a043ad8e1
 ---> a4cf55809b0f
Removing intermediate container 830a043ad8e1
Step 2 : CMD /bin/bash
 ---> Running in b544385655d3
 ---> 8f1b9adf297c
Removing intermediate container b544385655d3
Successfully built 8f1b9adf297c
root@ubuntu14-04:/home/kmaringanti/voltest# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
voltest             latest              8f1b9adf297c        4 seconds ago       101.4 MB
	
root@ubuntu14-04:/home/kmaringanti/voltest# docker run -it voltest
root@24a61c3e232c:/#
root@24a61c3e232c:/# ls -l
total 68
drwxr-xr-x   2 root root 4096 Nov  4 20:31 bin
drwxr-xr-x   2 root root 4096 Oct  8 10:11 boot
drwxr-xr-x   2 root root 4096 Nov 30 11:51 data
drwxr-xr-x   5 root root  380 Nov 30 11:51 dev
drwxr-xr-x  35 root root 4096 Nov 30 11:51 etc
drwxr-xr-x   2 root root 4096 Oct  8 10:11 home
drwxr-xr-x   8 root root 4096 Nov  4 20:31 lib
drwxr-xr-x   2 root root 4096 Nov  4 20:30 lib64
drwxr-xr-x   2 root root 4096 Nov  4 20:30 media
drwxr-xr-x   2 root root 4096 Nov  4 20:30 mnt
drwxr-xr-x   2 root root 4096 Nov  4 20:30 opt
dr-xr-xr-x 127 root root    0 Nov 30 11:51 proc
drwx------   2 root root 4096 Nov  4 20:31 root
drwxr-xr-x   5 root root 4096 Nov 16 20:58 run
drwxr-xr-x   2 root root 4096 Nov 16 20:58 sbin
drwxr-xr-x   2 root root 4096 Nov  4 20:30 srv
dr-xr-xr-x  13 root root    0 Nov 30 09:08 sys
drwxrwxrwt   2 root root 4096 Nov  4 20:31 tmp
drwxr-xr-x  11 root root 4096 Nov 16 20:58 usr
drwxr-xr-x  13 root root 4096 Nov 16 20:58 var
root@24a61c3e232c:/data# cat >hello.txt
sample hello file
^C
root@24a61c3e232c:/data#
root@24a61c3e232c:/data# cat hello.txt
sample hello file
root@24a61c3e232c:/data#
root@24a61c3e232c:/data#
root@ubuntu14-04:/home/kmaringanti/voltest# docker inspect 24a61c3e232c
[{
    "AppArmorProfile": "",
    "Args": [],
    "Config": {
        "AttachStderr": true,
        "AttachStdin": true,
        "AttachStdout": true,
 ...
 ...
 ...

 "Volumes": {
        "/data": "/var/lib/docker/vfs/dir/892afffa2ffa03148c80df071a3252026b6a869cad90f9f848bd6b7d4dea959a"
    },
    "VolumesRW": {
        "/data": true
    }
}
]
	
root@ubuntu14-04:/home/kmaringanti/voltest# cat /var/lib/docker/vfs/dir/892afffa2ffa03148c80df071a3252026b6a869cad90f9f848bd6b7d4dea959a/hello.txt
sample hello file
root@ubuntu14-04:/home/kmaringanti/voltest#


Here’s the twist

As you suppose that the file is persisted, but when the new container is created the data wont be there in the next container /data location.

Now try stopping the container

root@ubuntu:/home/kmaringanti/voltest# docker stop 24a61c3e232c


Run the container again and check the /data folder you will see that the file is not present.

root@ubuntu:/home/kmaringanti/voltest# docker run -it voltest
root@9e490ecbc6d2:/#
root@9e490ecbc6d2:/#
root@9e490ecbc6d2:/# ll
total 76
drwxr-xr-x  35 root root 4096 Dec  8 13:54 ./
drwxr-xr-x  35 root root 4096 Dec  8 13:54 ../
-rwxr-xr-x   1 root root    0 Dec  8 13:54 .dockerenv*
-rwxr-xr-x   1 root root    0 Dec  8 13:54 .dockerinit*
drwxr-xr-x   2 root root 4096 Nov 21 20:35 bin/
drwxr-xr-x   2 root root 4096 Oct  8 10:11 boot/
drwxr-xr-x   2 root root 4096 Dec  8 13:54 data/
drwxr-xr-x   5 root root  380 Dec  8 13:54 dev/
drwxr-xr-x  35 root root 4096 Dec  8 13:54 etc/
drwxr-xr-x   2 root root 4096 Oct  8 10:11 home/
drwxr-xr-x   8 root root 4096 Nov 21 20:35 lib/
drwxr-xr-x   2 root root 4096 Nov 21 20:35 lib64/
drwxr-xr-x   2 root root 4096 Nov 21 20:35 media/
drwxr-xr-x   2 root root 4096 Nov 21 20:35 mnt/
drwxr-xr-x   2 root root 4096 Nov 21 20:35 opt/
dr-xr-xr-x 143 root root    0 Dec  8 13:54 proc/
drwx------   2 root root 4096 Nov 21 20:35 root/
drwxr-xr-x   5 root root 4096 Nov 29 20:04 run/
drwxr-xr-x   2 root root 4096 Nov 29 20:04 sbin/
drwxr-xr-x   2 root root 4096 Nov 21 20:35 srv/
dr-xr-xr-x  13 root root    0 Dec  8 13:52 sys/
drwxrwxrwt   2 root root 4096 Nov 21 20:35 tmp/
drwxr-xr-x  11 root root 4096 Nov 29 20:04 usr/
drwxr-xr-x  13 root root 4096 Nov 29 20:04 var/	
	
root@9e490ecbc6d2:/# cd data/
root@9e490ecbc6d2:/data# ls
root@9e490ecbc6d2:/data#


even after doing inspect you will not find the files

root@ubuntu:/home/kmaringanti/voltest# docker inspect 9e490ecbc6d2
[{
    "AppArmorProfile": "",

	...
	...

    },
    "Volumes": {
        "/data": "/var/lib/docker/vfs/dir/bbb6ac732d971ae6850ae27c3e298feac7341241f568870f6e5b1afb7c65a8be"
    },
    "VolumesRW": {
        "/data": true
    }
}

root@ubuntu:/home/kmaringanti/voltest#
root@ubuntu:/home/kmaringanti/voltest#
root@ubuntu:/home/kmaringanti/voltest# ll /var/lib/docker/vfs/dir/bbb6ac732d971ae6850ae27c3e298feac7341241f568870f6e5b1afb7c65a8be/
total 8
drwxr-xr-x  2 root root 4096 Dec  8 07:54 ./
drwx------ 12 root root 4096 Dec  8 07:54 ../

First change needed to be observed is the volumes which are mapped in the host are different when the container is created. And the file is present in the previously created volume and not the new one.

Secondly volumes are created everytime the container is created. And hence the volume mapped to the hosts also are changed. This only happens when we don’t specify the mapping volume in host.

Now run this command with volume attached and after inspect check the Volumesand you will now see the host folder location where the files are saved. Also try creating a file, kill the container and start again with same host volume location as mentioned below.

And hence everytime when the container is run, always mention the host folder location mapped for data persistence.

root@ubuntu:/home/kmaringanti/voltest# docker run -it -v /home/kmaringanti/voltest/data:/data voltest
root@ubuntu:/home/ubuntu/test# docker inspect fdc808f890bd
[{
    "AppArmorProfile": "",
    "Args": [],
    "Config": {
        "AttachStderr": true,
        "AttachStdin": true,
		...
		...
   "RestartCount": 0,
    "State": {
        "Dead": false,
        "Error": "",
        "ExitCode": 0,
        "FinishedAt": "0001-01-01T00:00:00Z",
        "OOMKilled": false,
        "Paused": false,
        "Pid": 5762,
        "Restarting": false,
        "Running": true,
        "StartedAt": "2016-12-08T15:09:40.205175421Z"
    },
    "Volumes": {
        "/data": "/home/ubuntu/test/data"
    },
    "VolumesRW": {
        "/data": true
    }
}