DEV Community

Stephen Afam-Osemene
Stephen Afam-Osemene

Posted on • Originally published at stephenafamo.com on

Docker Volumes: An Introduction

Docker volume

Docker volumes are very useful when we need to persist data in Docker containers or share data between containers.

Docker volumes are important because when a Docker container is destroyed, it’s entire file system is destroyed too. So if we want to keep this data in some way, it is necessary that we use Docker volumes.

Docker volumes are attached to containers during a docker run command by using the -v flag

When Docker Volumes are needed

Let’s look at the docker image we created in a previous article. The stephenafamo/adonisjs image.

The working directory is /var/www, and the application code is there. If we want to run an Adonis application in a container from this image and we don’t want all our files to be deleted once we stop the container, then we have several choices.

1. Bind mounts

A bind mount is just mapping a directory on the host machine to a directory in the container. However, when the container is removed, it does not affect the directory.

If the -v or --volume flag’s value is a path, then it is assumed to be a bind mount. If the directory does not exist, then it will be created. When we do this, the directory /path/to/app/directory will contain the same files as /var/www in the container.

docker run -d --name adonis \
    -v /path/to/app/directory:/var/www \
    stephenafamo/adonisjs:1.0.0
Enter fullscreen mode Exit fullscreen mode

NOTE : If you are confused about how to use the docker run command or how to run containers, then you can go through the the previous article.

2. Docker volumes

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure of the host machine, volumes are completely managed by Docker. Volumes have several advantages over bind mounts:

  • Volumes are easier to back up or migrate than bind mounts.
  • You can manage volumes using Docker CLI commands or the Docker API.
  • Volumes work on both Linux and Windows containers.
  • Volumes can be more safely shared among multiple containers.
  • Volume drivers allow you to store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.
  • A new volume’s contents can be pre-populated by a container.

In addition, volumes are often a better choice than persisting data in a container’s writable layer, because using a volume does not increase the size of containers using it, and the volume’s contents exist outside the lifecycle of a given container.

Creating and Removing a Docker volume

We can create a Docker volume using the command

docker volume create volume_name
Enter fullscreen mode Exit fullscreen mode

To list all the volumes, we use the following command.

docker volume ls
Enter fullscreen mode Exit fullscreen mode

docker volume ls
docker volume ls

If we ever choose to delete a Docker volume, we do it using the command.

docker volume rm volume_name
Enter fullscreen mode Exit fullscreen mode

Attaching a Docker volume to a container

We can also use the -v or --volume flag to attach a Docker volume to a container. However, instead of putting the path to the directory on the host machine as we did with bind mounts, we simply put the volume name.

docker run -d --name adonis \
    -v adonis_vol:/var/www \
    stephenafamo/adonisjs:1.0.0
Enter fullscreen mode Exit fullscreen mode

NOTE : If we specify a volume that does not exist, it will be created

Mounting new Docker volumes or empty directories

If we start a container that creates a new volume and attach it to a destination in the container that contains files, then the files in the destination are copied into the volume.

For example, in our stephenafamo/adonisjs image, a new application will be created in the /var/www directory if an empty volume is mounted there.

Using a mount in read-only mode

Since a Docker volume (or bind mount) can be attached to multiple containers, it may be useful for only some of the containers to be able to write to it.

To achieve this, we will need to attach the volume to the other containers in read-only mode. This is done by adding the ro option like this;

docker run -d --name adonis \
    -v adonis_vol:/var/www:ro \
    stephenafamo/adonisjs:1.0.0
Enter fullscreen mode Exit fullscreen mode

This works for both Docker volumes and bind mounts.

Conclusion

So, this covers the common uses of Docker volumes. There are also several volume drivers that allow for some more functionality. Perhaps we’ll talk about that in another article, or maybe I’ll update this later.

As always, I appreciate comments, suggestions and corrections. Thank you.

The post Docker Volumes: An Introduction appeared first on Stephen AfamO's Blog.

Top comments (2)

Collapse
 
cduv profile image
DUVERGIER Claude

I don't understand that part:

If we start a container that creates a new volume, or mount an empty directory to a destination in the container that contains files, then the files in the destination are copied into the volume or empty directory.

It means that with the following image:

FROM busybox
RUN echo "foo" > /data/bar
VOLUME /data
CMD ["/bin/sh"]

Built and executed as follows

docker build -t my-sample-image .
mkdir -p /tmp/my-temp-dir
docker run -d --name my-sample \
    -v  /tmp/my-temp-dir:/data \
    my-sample-image

I would have a file bar in /tmp/my-temp-dir?
I don't know for Docker volumes but I doubt the container's /data/bar file which was created during the docker build (making /data/bar part of the Docker image basically) would be back-copied into host's /tmp/my-temp-dir directory...

Usually when you mount host's /tmp/my-temp-dir as container's /data/bar, any content of container/image's /data/bar is replaced. That's why so many images have a setup/fill part in their entrypoint's script.

Collapse
 
stephenafamo profile image
Stephen Afam-Osemene

You are correct, and I have edited the article to reflect this. Thank you.