Skip to content
James CarppeJune 12, 20244 min read

Persistent Storage: Docker Bind Mounts and Named Volumes

Persistent storage in containerization can be a complex topic to cover. In this first post in a series of blog posts, we'll be looking at persistent storage concepts in Docker, specifically the difference between bind mounts and named volumes.

What is Persistent Storage?

Before we dive into the Docker specifics, let's look at what we mean by persistent storage.

Containers are intended to be "idempotent" - that is, you should be able to destroy a container and create a replacement without any data loss. When you have a basic container that performs an action, you often don't need to worry too much about persistent storage. However, once you start working with containers that do need to have data persistency (for example, a database), the idempotency of a container will start to become a problem. If you want to save entries to a database in your container, without persistent storage that data would be lost when the container is recreated.

Persistent storage provides an option to keep that data outside of the container, but still accessible by it, so that it can survive a container recreation.

Docker and Volumes

In Docker, a volume is a way for a container to be given persistent storage for files that are outside of the image itself but need to remain through restarts of the container.

PRT0033 - Second Course Diagrams - v17

There are two primary types of volumes available in Docker: bind mounts and named volumes. Each type has it's own benefits and drawbacks, functioning in different ways externally but both appearing in the same way to the container's internal file system.

Bind mounts

A bind mount is fairly straightforward - it is a way to mount a directory from the host machine into your container. You simply define the directory on your host system (for example, /mnt/nginx) and the path where you'd like it to appear within your container's filesystem (for example, /usr/share/nginx/html). That's it.

While simple, there are certain considerations you should keep in mind when using bind mounts. Because you are mounting your host filesystem into your container, your container has access to that filesystem. This could be a security issue if you're running an insecure or malicious container image. A bind mount is also managed outside of the Docker orchestrator, so you would need to ensure that the directory stays at that path, has the right permissions, and isn't modified unexpectedly by other processes on the host system.

Named volumes

Named volumes, often simply referred to as "volumes", are Docker's answer to managed persistent storage. When you create a named volume, Docker builds a virtual file system that can then be attached to a container (or multiple containers) to serve as persistent storage. This virtual file system, while existing on the host, is managed by Docker itself. As such, you're not mounting the host filesystem directly into your container at all, unlike with a bind mount.

Named volumes are generally created independently of a container, as after all they are a separate object. In Portainer, this can be done through the Volumes page by clicking Add volume and filling in the details. You can find more information on this in our documentation.

docker-volume-create-create

Once a named volume has been created, you can mount it to a container by selecting the volume and the path where you'd like it to appear within your container's filesystem (much like a bind mount above). Because the volume is referenced by a name rather than a path, this makes it more portable especially when you consider how different paths may work on different OSes and deployments.

Named volumes can also be created as part of a stack definition through the use of a separate volumes section alongside the services section you would use to define your containers. They can then be referenced in the volumes subsection of your service definitions in the same YAML file.

There are of course cases where a named volume might not make sense - for example, if you had a directory with a large amount of files that you wanted to make available to other services outside of your container, but in many situations using a named volume can provide you with benefits that a bind mount cannot. 

What about network volumes?

Docker also supports the mounting of network volumes (such as NFS or CIFS shares) within a container, and these essentially work in a similar way to a bind mount in that you provide the source path (and often in the case of a network mount the necessary access credentials) and the path to mount within the container file system. Also much like bind mounts, network volumes are managed outside of Docker so don't have the benefits of named volumes. 

Learning more

For a more in-depth dive into persistent storage in Docker, have a look at our Deploying on Docker with Portainer course in the Portainer Academy. There we work through the concepts of Docker including volumes, along with example deployments to get you understanding the concepts by employing them directly.

 

In the next post in this series we'll be building upon the basic concepts we've covered here for Docker and looking at how persistent storage applies to the world of Kubernetes.

avatar

James Carppe

A former web developer, operations manager, and radio announcer, James is a big fan of technology in all forms. When not making videos and helping Portainer customers out, you'll often find him watching films and television, pretending to be a photographer, and tinkering with the latest gadgets.

COMMENTS

Related articles