Earlier, we described the steps towards creating a data volume in a Docker image using the VOLUME instruction in the Dockerfile. However, Docker does not provide any mechanism to mount the host directory or file during the build time in order to ensure the Docker images are portable. The only provision Docker provides is to mount the host directory or file to a container's data volume during the container's launch time. Docker exposes the host directory or file mounting facility through the -v option of the docker run subcommand. The –v option has three different formats enumerated as follows:
1. -v <container mount path>
2. -v <host path>/<container mount path>
3. -v <host path>/<container mount path>:<read write mode>
The <host path> is an absolute path in the Docker host, <container mount path> is an absolute path in the container filesystem, and <read write mode> can be either read-only (ro) or read-write (rw) mode. The first -v <container mount path> format has already been explained in the Data Volume section in this chapter, as a method to create a mount point during the container launch time. The second and third options enable us to mount a file or directory from the Docker host to the container mount point.
We would like to dig deeper to gain a better understanding of the host's data sharing through a couple of examples. In the first example, we will demonstrate how to share a directory between the Docker host and the container, and in the second example, we will demonstrate file sharing.
Here, in the first example, we mount a directory from the Docker host to a container, perform a few basic file operations on the container, and verify these operations from the Docker host, as detailed in the following steps:
1. First, let's launch an interactive container with the –v option of the docker run subcommand to mount /tmp/hostdir of the Docker host directory to /MountPoint of the container:
$ sudo docker run -v /tmp/hostdir:/MountPoint \ -it ubuntu:14.04
If /tmp/hostdir is not found on the Docker host, the Docker
engine will create the directory itself. However, the problem is that the system-generated directory cannot be deleted using the
-v option of the docker rm subcommand.
2. Having successfully launched the container, we can check the presence of /MountPoint using the ls command:
root@4a018d99c133:/# ls -ld /MountPoint
drwxr-xr-x 2 root root 4096 Nov 23 18:28 /MountPoint 3. Now, we can proceed to checking the mount details using the
mount command:
root@4a018d99c133:/# mount ... TRUNCATED OUTPUT ...
/dev/disk/by-uuid/721cedbd-57b1-4bbd-9488-ec3930862cf5 on /MountPoint type ext3 (rw,noatime,nobarrier,errors=remount- ro,data=ordered)
... TRUNCATED OUTPUT ...
4. Here, we are going to validate /MountPoint, change to the /MountPoint directory using the cd command, create a few files using the touch command, and list the files using the ls command, as shown in the following script:
root@4a018d99c133:/# cd /MountPoint/
root@4a018d99c133:/MountPoint# touch {a,b,c} root@4a018d99c133:/MountPoint# ls -l
total 0
5. It might be worth the effort to verify the files in the /tmp/hostdir Docker host directory using the ls command on a new terminal, as our container is running in an interactive mode on the existing terminal:
$ sudo ls -l /tmp/hostdir/ total 0
-rw-r--r-- 1 root root 0 Nov 23 12:39 a -rw-r--r-- 1 root root 0 Nov 23 12:39 b -rw-r--r-- 1 root root 0 Nov 23 12:39 c
Here, we can see the same set of files, as we can see in step 4. However, you might have noticed the difference in the time stamp of the files. This time difference is due to the time-zone difference between the Docker host and the container.
6. Finally, let's run the docker inspect subcommand with the container ID 4a018d99c133 as an argument to see whether the directory mapping is set up between the Docker host and the container mount point, as shown in the following command:
$ sudo docker inspect \
--format={{.Volumes}} 4a018d99c133 map[/MountPoint:/tmp/hostdir]
Apparently, in the preceding output of the docker inspect subcommand, the /tmp/hostdir directory of the Docker host is mounted on the
/MountPoint mount point of the container.
For the second example, we can mount a file from the Docker host to a container, update the file from the container, and verify these operations from the Docker host, as detailed in the following steps:
1. In order to mount a file from the Docker host to the container, the file must preexist in the Docker host. Otherwise, the Docker engine will create a new directory with the specified name, and mount it as a directory. We can start by creating a file on the Docker host using the touch command:
$ touch /tmp/hostfile.txt
2. Launch an interactive container with the –v option of the docker run subcommand to mount the /tmp/hostfile.txt Docker host file to the container as /tmp/mntfile.txt:
$ sudo docker run -v /tmp/hostfile.txt:/mountedfile.txt \ -it ubuntu:14.04
3. Having successfully launched the container, now let's check the presence of /mountedfile.txt using the ls command:
root@d23a15527eeb:/# ls -l /mountedfile.txt
-rw-rw-r-- 1 1000 1000 0 Nov 23 19:33 /mountedfile.txt 4. Then, proceed to check the mount details using the mount command:
root@d23a15527eeb:/# mount ... TRUNCATED OUTPUT ...
/dev/disk/by-uuid/721cedbd-57b1-4bbd-9488-ec3930862cf5 on /mountedfile.txt type ext3
(rw,noatime,nobarrier,errors=remount-ro,data=ordered) ... TRUNCATED OUTPUT ...
5. Then, update some text to /mountedfile.txt using the echo command: root@d23a15527eeb:/# echo "Writing from Container" \
> mountedfile.txt
6. Meanwhile, switch to a different terminal in the Docker host, and print the /tmp/hostfile.txt Docker host file using the cat command: $ cat /tmp/hostfile.txt
Writing from Container
7. Finally, run the docker inspect subcommand with the container ID d23a15527eeb as it's argument to see the file mapping between the Docker host and the container mount point:
$ sudo docker inspect \
--format={{.Volumes}} d23a15527eeb map[/mountedfile.txt:/tmp/hostfile.txt]
From the preceding output, it is evident that the /tmp/hostfile.txt file from the Docker host is mounted as /mountedfile.txt inside the container.
In the case of file sharing between the Docker host and container, the file must exist before launching the container. However, in the case of directory sharing, if the directory does not exist in the Docker host, then the Docker engine would create a new directory in the Docker host, as explained earlier.