When deploying Docker containers, the official docs recommends the use of named volumes over bind mounts. Yet, for many containers, the example setup configuration tends to feature bind mounts. It’s hard to blame them, though: bind mounts are a lot more intuitive than volumes, named or otherwise. In this post, I would like to briefly share my thoughts on some arguments related to choosing between the two.
This is just a really brief recap of what bind mounts and volumes are. If you’re looking for more, it’s best to consult the official docs directly.
Bind mounts #
Bind mounts are mappings between a manually-specified directory or file on the host, and the guest (container). They are declared in the form
/path/on/host:/path/on/guest, with the colon differentiating between host and guest.
Volumes are storage directories created and managed by Docker, e.g. via the
docker volume create command. Similar to bind mounts, they can be attached to containers in the following form:
There are two types of volumes, anonymous and named. This post primarily makes reference to named volumes.
Why bind mounts? #
Ease of backup #
The official Docker docs has this to say regarding the benefits of volumes:
Volumes are easier to back up or migrate than bind mounts.
It then goes on about how you can easily do so:
- Create a new, temporary container
- Launch the new container
- Mount the volume to be backed up, and
- Attach another local host directory via bind mount
tarthe contents of the volume to the bound directory
- (Optional) delete the temporary container
In comparison, backing up bind mounts involves the following step:
tarthe contents of the bind mount
In my opinion, it’s clear that backing up bind mounts is a less involved process. And restoring from backups is easier too, as it basically involves the same set of steps, just extracting instead of archiving.
Granted, it isn’t very difficult to spin up a simple Alpine or Ubuntu container for backing up files. Still, I believe it’s probably safe to say that compared to volumes, bind mounts are easier to backup and restore.
Ease of modifying files #
For the same reasons bind mounts are easier to backup, it is also easier to modify files which are shared with containers. That means it is easier to reference files which may need to be modified by users, e.g. configuration files, via bind mounts than using volumes.
Why volumes? #
Because volumes are fully controlled by the Docker daemon, some operations become simpler/possible. For example, it’s possible to manage volumes via the Docker CLI and Docker Engine API, though at the time of writing, there are very few commands available:
It’s also possible, on Linux hosts, to specify driver options for the built-in
local volume driver. Thus, one can directly mount NFS shares via Docker Engine, without having to first ensure it is mounted on the host. This can simplify the sharing of volumes across multiple hosts (e.g. in a Swarm configuration).
Isolation from host #
For certain applications, it almost never makes sense to have direct access to the raw files (e.g. databases). In such situations, the isolation Docker enforces on volumes can be a plus: it is able to help reduce the odds of accidental modification, be it by users or other programs.
Which is better? #
At its heart, volumes are really Docker-controlled bind mounts. They exist, by default, under
/var/lib/docker/volumes, and are not meant to be directly modified/controlled by users. Otherwise, both are still subject to the host filesystem.
When I was just starting out with Docker, and containers in general, I had difficulties wrapping my head around why anyone would prefer using volumes. And it turns out that for simple use-cases like self-hosting various services for personal (friends and family) use, it doesn’t really matter.
Of course, if you’re deploying containers for business applications, you would definitely want to conduct a proper analysis of your system requirements. Otherwise, if you’re just a “casual sysadmin”, I believe the convenience bind mounts offer makes it a compelling choice. And if the data needs to be accessed by multiple containers (ala Docker Swarm), consider using volumes.
TL;DR: for small, single-machine setups, it probably doesn’t matter — okay to use bind mounts for their convenience. If deploying across multiple machines (via Swarm and co), volumes are likely more suitable.
Just avoid persisting data directly in a container’s write layer.