21 Days of Docker-Day 13 -Docker Storage – Part 2

  • Pay special attention to entry Mountpoint
  • If you perform ls -l , you will see all the content of /etc directory of the container
# ls -l /var/lib/docker/volumes/mytestvol/_data
total 104
-rw-r--r-- 1 root root     7 Aug 20 10:30 alpine-release
drwxr-xr-x 4 root root    88 Oct 18 00:27 apk
drwxr-xr-x 2 root root     6 Aug 20 10:30 conf.d
drwxr-xr-x 2 root root    18 Oct 18 00:27 crontabs
-rw-r--r-- 1 root root    89 Jun 17 09:00 fstab
-rw-r--r-- 1 root root   697 Jun 17 09:00 group
-rwxr-xr-x 1 root root     0 Oct 18 00:27 hostname
-rwxr-xr-x 1 root root     0 Oct 18 00:27 hosts
drwxr-xr-x 2 root root     6 Aug 20 10:30 init.d
-rw-r--r-- 1 root root   570 Jun 17 09:00 inittab
-rw-r--r-- 1 root root    54 Aug 20 10:30 issue
drwxr-xr-x 2 root root    19 Oct 18 00:27 logrotate.d
drwxr-xr-x 2 root root    81 Oct 18 00:27 modprobe.d
-rw-r--r-- 1 root root    15 Jun 17 09:00 modules
drwxr-xr-x 2 root root     6 Aug 20 10:30 modules-load.d
-rw-r--r-- 1 root root   283 Jun 17 09:00 motd
lrwxrwxrwx 1 root root    12 Oct 18 00:27 mtab -> /proc/mounts
drwxr-xr-x 8 root root   120 Oct 18 00:27 network
drwxr-xr-x 2 root root     6 Aug 20 10:30 opt
-rw-r--r-- 1 root root   164 Aug 20 10:30 os-release
-rw-r--r-- 1 root root  1230 Jun 17 09:00 passwd
drwxr-xr-x 7 root root    75 Oct 18 00:27 periodic
-rw-r--r-- 1 root root   279 Jun 17 09:00 profile
drwxr-xr-x 2 root root    26 Oct 18 00:27 profile.d
-rw-r--r-- 1 root root  1865 Jun 17 09:00 protocols
-rwxr-xr-x 1 root root     0 Oct 18 00:27 resolv.conf
-rw-r--r-- 1 root root    65 Jun 12 17:52 securetty
-rw-r--r-- 1 root root 36141 Jun 17 09:00 services
-rw-r----- 1 root   42   441 Aug 20 10:30 shadow
-rw-r--r-- 1 root root    38 Jun 17 09:00 shells
drwxr-xr-x 5 root root   156 Oct 18 00:27 ssl
-rw-r--r-- 1 root root    53 Jun 17 09:00 sysctl.conf
drwxr-xr-x 2 root root    28 Oct 18 00:27 sysctl.d
-rw-r--r-- 1 root root  4169 Jun 12 17:52 udhcpd.conf
  • Now stop and delete the container
# docker stop 0dbffcc4beb9
0dbffcc4beb9

# docker rm 0dbffcc4beb9
0dbffcc4beb9
  • Verify the content of /var/lib/docker
# ls -l /var/lib/docker/volumes/mytestvol/_data
total 104
-rw-r--r-- 1 root root     7 Aug 20 10:30 alpine-release
drwxr-xr-x 4 root root    88 Oct 18 00:27 apk
drwxr-xr-x 2 root root     6 Aug 20 10:30 conf.d
drwxr-xr-x 2 root root    18 Oct 18 00:27 crontabs
-rw-r--r-- 1 root root    89 Jun 17 09:00 fstab
-rw-r--r-- 1 root root   697 Jun 17 09:00 group
-rwxr-xr-x 1 root root     0 Oct 18 00:27 hostname
-rwxr-xr-x 1 root root     0 Oct 18 00:27 hosts
drwxr-xr-x 2 root root     6 Aug 20 10:30 init.d
-rw-r--r-- 1 root root   570 Jun 17 09:00 inittab
-rw-r--r-- 1 root root    54 Aug 20 10:30 issue
drwxr-xr-x 2 root root    19 Oct 18 00:27 logrotate.d
drwxr-xr-x 2 root root    81 Oct 18 00:27 modprobe.d
-rw-r--r-- 1 root root    15 Jun 17 09:00 modules
drwxr-xr-x 2 root root     6 Aug 20 10:30 modules-load.d
-rw-r--r-- 1 root root   283 Jun 17 09:00 motd
lrwxrwxrwx 1 root root    12 Oct 18 00:27 mtab -> /proc/mounts
drwxr-xr-x 8 root root   120 Oct 18 00:27 network
drwxr-xr-x 2 root root     6 Aug 20 10:30 opt
-rw-r--r-- 1 root root   164 Aug 20 10:30 os-release
-rw-r--r-- 1 root root  1230 Jun 17 09:00 passwd
drwxr-xr-x 7 root root    75 Oct 18 00:27 periodic
-rw-r--r-- 1 root root   279 Jun 17 09:00 profile
drwxr-xr-x 2 root root    26 Oct 18 00:27 profile.d
-rw-r--r-- 1 root root  1865 Jun 17 09:00 protocols
-rwxr-xr-x 1 root root     0 Oct 18 00:27 resolv.conf
-rw-r--r-- 1 root root    65 Jun 12 17:52 securetty
-rw-r--r-- 1 root root 36141 Jun 17 09:00 services
-rw-r----- 1 root   42   441 Aug 20 10:30 shadow
-rw-r--r-- 1 root root    38 Jun 17 09:00 shells
drwxr-xr-x 5 root root   156 Oct 18 00:27 ssl
-rw-r--r-- 1 root root    53 Jun 17 09:00 sysctl.conf
drwxr-xr-x 2 root root    28 Oct 18 00:27 sysctl.d
-rw-r--r-- 1 root root  4169 Jun 12 17:52 udhcpd.conf
  • As you can see, now the content inside the container is independent of the lifecycle of the container
  • To delete a Volume
# docker volume rm mytestvol
mytestvol
  • Let’s try to perform the same with the help of Dockerfile
FROM busybox
RUN mkdir /mytestvol
RUN echo "testing volume" >> /mytestvol/test.txt
VOLUME /mytestvol
  • Most of the steps are self-explanatory except for additional Volume directive
  • The VOLUME instruction creates a mount point with the specified name and marks it as holding externally mounted volumes from the native host or other containers.
  • Build the image
$ docker build -t mytestvol .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM busybox
latest: Pulling from library/busybox
7c9d20b9b6cd: Pull complete 
Digest: sha256:fe301db49df08c384001ed752dff6d52b4305a73a7f608f21528048e8a08b51e
Status: Downloaded newer image for busybox:latest
 ---> 19485c79a9bb
Step 2/4 : RUN mkdir /mytestvol
 ---> Running in 0ccb934b0aaa
Removing intermediate container 0ccb934b0aaa
 ---> 4c1588d68117
Step 3/4 : RUN echo "testing volume" >> /mytestvol/test.txt
 ---> Running in 62670ec07b44
Removing intermediate container 62670ec07b44
 ---> cc7e62902148
Step 4/4 : VOLUME /mytestvol
 ---> Running in a9ac690bcc4b
Removing intermediate container a9ac690bcc4b
 ---> 95aed0e870d1
Successfully built 95aed0e870d1
Successfully tagged mytestvol:latest
  • Run the container using this image
# docker container run -dt --name mytestvol 95aed0e870d1 sh
3c7d432c8fb184363b2229c9a441c0d5fa434eaece3c44d0849012bef92c5121
  • Verify the Volume directory
# ls -l /var/lib/docker/volumes/00d11f4265813642f1cf178d0bdb04f90a76fb85eedda176482c46b822b3fb2f/_data/
total 4
-rw-r--r-- 1 root root 15 Oct 18 00:38 test.txt
  • You can also verify the volume
# docker volume ls
DRIVER              VOLUME NAME
local               00d11f4265813642f1cf178d0bdb04f90a76fb85eedda176482c46b822b3fb2f
  • Now one major problem with this approach is that Docker is assigning random name to this volume and when you have thousand of Volume in your system, its pretty difficult to find out which volume is associated with which container
  • To overcome this problem, you can assign a name to your volume
# docker container run -dt --name mytestvol01 -v testvol:/mytestvol 95aed0e870d1 sh
0f3706adbbb961ba55fd134f9c1be0a45ed1c9180d1002aa43ac297e981e54e9
  • Verify it
# docker volume ls
DRIVER              VOLUME NAME
local               00d11f4265813642f1cf178d0bdb04f90a76fb85eedda176482c46b822b3fb2f
local               testvol
  • Check it
# ls -l /var/lib/docker/volumes/testvol/_data/
total 4
-rw-r--r-- 1 root root 15 Oct 18 00:38 test.txt

Bind Mount

  • One of the major difference between Volume and Bind Mount is in case of Volume are stored in a part of the host filesystem which is managed by Docker whereas in case of a Bind mount may be stored anywhere on the host system.
  • I already mentioned the bind mount previously, so quickly skim through it
  • Create a directory and test file
$ mkdir index
$ echo "hello from bind mount" >> index/index.html
  • Create and run the container
$ docker run -dt --name mybindmount -v ~/index:/usr/share/nginx/html -p 8080:80 nginx
4b7bd0830020df15efb83097a0956bd47e5acc80baa39f0bbf9629a8c4c0c401
  • Test it
$ curl localhost:8080
hello from bind mount

NOTE: If you notice there is some difference between bind mount and volume, in case of Volume I specify the Volume name, whereas in case of bind mount, I specify the path

docker container run -dt --name mytestvol01 -v testvol:/mytestvol 95aed0e870d1 sh
  • There is one more way you can specify the bind mount
docker container run -dt --name mybindmount01 --mount type=bind,source=/home/cloud_user/index,target=/usr/share/nginx/html -p 8081:80 nginx
7845a6d076b579e4047b1bcae765c0a35daeeccfe614f0b0b2609fc52a9a27f1
  • We can also create a read-only bind mount
$ docker container run -dt --name mybindmount03 --mount type=bind,source=/home/cloud_user/index,target=/usr/share/nginx/html,readonly -p 8082:80 nginx
6b58ea0672be83db8c1809d04a50a335685f882989ad2682c348a57b349bdea7
  • Remove all unused local volumes
$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B

Please follow me with my Journey

This time to make learning more interactive, I am adding

  • Slack
  • Meetup

Please feel free to join this group.

Slack: 

https://100daysofdevops.slack.com/join/shared_invite/enQtNzg1MjUzMzQzMzgxLWM4Yjk0ZWJiMjY4ZWE3ODBjZjgyYTllZmUxNzFkNTgxZjQ4NDlmZjkzODAwNDczOTYwOTM2MzlhZDNkM2FkMDA

Meetup Group

If you are in the bay area, please join this meetup group https://www.meetup.com/100daysofdevops/