Sharing host data

Earlier, we described the steps to create 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 to be 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. Docker exposes the host directory or file mounting facility through the -v option of the docker run subcommand. The -v option has five different formats, enumerated as follows:

  • -v <container mount path>
  • -v <host path>:<container mount path>
  • -v <host path>:<container mount path>:<read write mode>
  • -v <volume name>:<container mount path>
  • -v <volume name>:<container mount path>:<read write mode>

The <host path> format is an absolute path in the Docker host, <container mount path> is an absolute path in the container filesystem, <volume name> is the name of the volume created using the docker volume create subcommand, and <read write mode> can be either the 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 launch of the container launch. The second and third formats enable us to mount a file or directory from the Docker host to the container mount point. The fourth and fifth formats allow us to mount volumes created using the docker volume create subcommand.

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:16.04
If /tmp/hostdir is not found on the Docker host, the Docker Engine will create the directory per se. However, the problem is that the system-generated directory cannot be deleted using the -v option of the docker rm subcommand.
  1. 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
  1. Now, we can proceed to check the mount details using the mount command:
      root@4a018d99c133:/# mount | grep MountPoint
/dev/xvda2 on /MountPoint type ext3
(rw,noatime,nobarrier,errors=
remount-ro,data=ordered)
  1. 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
-rw-r--r-- 1 root root 0 Nov 23 18:39 a
-rw-r--r-- 1 root root 0 Nov 23 18:39 b
-rw-r--r-- 1 root root 0 Nov 23 18:39 c
  1. 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 saw in step 4. However, you might have noticed the difference in the timestamp of the files. This time difference is due to the time zone difference between the Docker host and the container.

  1. Finally, let's run the docker inspect subcommand with the 4a018d99c133 container ID 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='{{json .Mounts}}' 4a018d99c133
[{"Source":"/tmp/hostdir",
"Destination":"/MountPoint","Mode":"",
"RW":true,"Propagation":"rprivate"}]

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 will mount a file from the Docker host to a container, update the file from the container, and verify those 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
  1. 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:/mntfile.txt 
-it ubuntu:16.04
  1. Having successfully launched the container, now let's check the presence of /mntfile.txt using the ls command:
      root@d23a15527eeb:/# ls -l /mntfile.txt
-rw-rw-r-- 1 1000 1000 0 Nov 23 19:33 /mntfile.txt
  1. Then, proceed to check the mount details using the mount command:
      root@d23a15527eeb:/# mount | grep mntfile
/dev/xvda2 on /mntfile.txt type ext3
(rw,noatime,nobarrier,errors=remount-ro,data=ordered)
  1. Then, update some text to /mntfile.txt using the echo command:
      root@d23a15527eeb:/# echo "Writing from Container" 
> mntfile.txt
  1. 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
  1. Finally, run the docker inspect subcommand with the d23a15527eeb container ID as it's argument to see the file mapping between the Docker host and the container mount point:
      $ sudo docker inspect 
--format='{{json .Mounts}}' d23a15527eeb
[{"Source":"/tmp/hostfile.txt",
"Destination":"/mntfile.txt",
"Mode":"","RW":true,"Propagation":"rprivate"}]

From the preceding output, it is evident that the /tmp/hostfile.txt file from the Docker host is mounted as /mntfile.txt inside the container.

For the last example, we will create a Docker volume and mount a named data volume to a container. In this example, we are not going to run the verification steps as we did in the previous two examples. However, you are encouraged to run the verification steps we laid out in the first example.

  1. Create a named data volume using the docker volume create subcommand, as shown here:
      $ docker volume create --name namedvol
  1. Now, launch an interactive container with the -v option of the docker run subcommand to mount namedvol a named data value to /MountPoint of the container:
      $ sudo docker run -v namedvol:/MountPoint 
-it ubuntu:16.04
During the launch of the container, Docker Engine creates namedvol if it is not created already.
  1. Having successfully launched the container, you can repeat the verification steps 2 to 6 of the first example and you will find the same output pattern in this example as well.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset