5.9 Creating and Using Data Volume Containers

If you specify a single directory argument to the -v option of docker run, Docker creates the directory in the container and marks it as a data volume that other containers can mount. You can also use the VOLUME instruction in a Dockerfile to create this data volume in an image. A container that contains such a data volume is called a data volume container. After populating the data volume with files, you can use the --volumes-from option of docker run to have other containers mount the volume and access its data.

Note

When you use docker rm to remove a container that has associated data volumes, specify the -v option to remove these volumes. Unassociated volumes waste disk space and are difficult to remove.

The following example creates a data volume container that an HTTP server container can use as the source of its web content.

To create a data volume container image and an instance of a data volume container from this image:

  1. Make a directory where you can create the Dockerfile for the data volume container image, for example:

    # mkdir -p /var/docker_projects/mymod/dvc
  2. In the new directory, create a Dockerfile named Dockerfile that defines the image for a data volume container:

    # Dockerfile that modifies oraclelinux:7-slim to create a data volume container
    FROM oraclelinux:7-slim
    MAINTAINER A N Other <another@example.com>
    RUN mkdir -p /var/www/html
    RUN echo "This is the content for file1.html" > /var/www/html/file1.html
    RUN echo "This is the content for file2.html" > /var/www/html/file2.html
    RUN echo "This is the content for index.html" > /var/www/html/index.html
    VOLUME /var/www/html
    ENTRYPOINT /usr/bin/tail -f /dev/null

    The RUN instructions create a /var/www/html directory that contains three simple files.

    The VOLUME instruction makes the directory available as a volume that other containers can mount by using the --volumes-from option to docker run.

    The ENTRYPOINT instruction specifies the command that a container created from the image always runs. To prevent the container from exiting, the /usr/bin/tail -f /dev/null command blocks until you use a command such as docker stop dvc1 to stop the container.

  3. Use the docker build command to create the image:

    [root@host ~]# docker build --tag="mymod/dvc:v1" /var/docker_projects/mymod/dvc/
    Sending build context to Docker daemon  2.048kB
    Step 1/8 : FROM oraclelinux:7-slim
     ---> c2b5cb5bcd9d
    Step 2/8 : MAINTAINER A N Other <another@example.com>
     ---> Running in 56c7b79c246e
    Removing intermediate container 56c7b79c246e
     ---> 620ff82e21cb
    Step 3/8 : RUN mkdir -p /var/www/html
     ---> Running in ac91306f3d74
    Removing intermediate container ac91306f3d74
     ---> 379c58d9eab9
    Step 4/8 : RUN echo "This is the content for file1.html" > /var/www/html/file1.html
     ---> Running in 981773ba0210
    Removing intermediate container 981773ba0210
     ---> 2ee97d83b582
    Step 5/8 : RUN echo "This is the content for file2.html" > /var/www/html/file2.html
     ---> Running in 36e8550c9a8b
    Removing intermediate container 36e8550c9a8b
     ---> 4ba8d28df981
    Step 6/8 : RUN echo "This is the content for index.html" > /var/www/html/index.html
     ---> Running in 6f15a403b4f6
    Removing intermediate container 6f15a403b4f6
     ---> 550bb92c154b
    Step 7/8 : VOLUME /var/www/html
     ---> Running in 1806e5d6e643
    Removing intermediate container 1806e5d6e643
     ---> 0e3de4ac4c9c
    Step 8/8 : ENTRYPOINT /usr/bin/tail -f /dev/null
     ---> Running in 6cde4f965504
    Removing intermediate container 6cde4f965504
     ---> 5e4e2780503b
    Successfully built 5e4e2780503b
    Successfully tagged mymod/dvc:v1
  4. Create an instance of the data volume container, for example dvc1:

    [root@host ~]# docker run -d --name dvc1 mymod/dvc:v1 tail -f /dev/null
    259c825e5645c7205613b0187549fdb9cd0d2d4861328f4676dbfa3db6370fff

To test that other containers can mount the data volume (/var/www/html) from dvc1, create a container named websvr that runs an HTTP server and mounts its data volume from dvc1.

[root@host ~]# docker run -d --volumes-from dvc1 --name websvr -P mymod/httpd:v2
008ce3de1cbf98ce50f6e3f3cf7618d248ce9dcfca8c29c1d04d179118d4c1b3

After finding out the correct port to use on the host, use curl to test that websvr correctly serves the content of all three files that were set up in the image.

[root@host ~]# docker port websvr 80
0.0.0.0:32769
[root@host ~]# curl http://localhost:32769
This is the content for index.html
[root@host ~]# curl http://localhost:32769/file1.html
This is the content for file1.html
[root@host ~]# curl http://localhost:32769/file2.html
This is the content for file2.html