Docker Bind Mounts: A Quick Summary

Bind Mounts are a simple and efficient way to share data between a container and its host. They're particularly useful for developers working with Docker containers.

July 1, 2020 in Docker

One of the most important properties of containers is their volatility. Any modifications that a container applies to its underlying image will vanish after removing the container. If you want to persist data generated by a container, share data between a container and its host and make the data independent of the container's lifecycle, you have to choose between three mechanisms offered by Docker: volumes, bind mounts and tmpfs mounts.

Usage of Bind Mounts

When using a bind mount, a directory or file on the host system is directly mounted into the desired container. There are a couple of scenarios where this makes sense, developing a PHP application that runs inside a container being one of them.

The following command runs a container based on the official php:7.3-apache image that uses Apache as web server:

$ docker container run -d \
  -p 80:80 \
  --name app \
  -v $(pwd)/html-data:/var/www/html \
  php:7.3-apache

This example uses the --volume (or short -v) option to create a bind mount. The PHP source code is located in the local directory $(pwd)/html-data, which is mounted into the container at /var/www/html since this is Apache's document root. Therefore, the syntax for -v always is -v <source on the host>:<target in the container>.

Decoupling the source code from the development container perfectly makes sense here, because re-building the image and copying the entire project into the image filesystem for every code change would be ridiculous. The bind mount solves this problem: As soon as a file in the local html-data directory changes, that change automatically becomes visible for the container and Apache will always deliver the latest version of the file.

Docker Bind Mounts concept

Keep in mind that all paths have to be specified as absolute paths. On Linux, this can be done using $(pwd)/html-data or even /home/dominik/my-blog/html-data. On Windows using Docker Desktop, you can use paths like /c/users/dominik/my-blog/html-data.

Better Readability Using --mount

Strictly speaking, the abovementioned syntax wasn't complete yet: The -v option even takes an optional third argument for mount options. For example, we could mount the source code directory as a read-only mount using -v $(pwd)/html-data:/var/www/html:ro.

This syntax may get quite confusing, especially for people new to Docker. For that reason, Docker 17.06 introduced the --mount option for standalone containers, providing a self-explanatory syntax and better readability. It simply consists of multiple key-value pairs.

$ docker container run -d \
  -p 80:80 \
  --name app \
  --mount type=bind,source=$(pwd)/html-data,destination=/var/www/html \
  php:7.3-apache

Yes, this option is a bit longer - but its explicit nature dramatically increases the readability and avoids possible misconceptions. In contrast to -v, the order of arguments doesn't matter anymore. Verifying that the bind mount has been created works as follows:

$ docker container inspect -f "{{.Mounts}}" app

More Possibilities Using --mount

Besides these advantages, --mount is also the more powerful option. Not only does it allow to specify bind mounts, but also to create other mount types like volumes. Here's a quick overview of all valid keys for --mount:

  • type: Defines the mount type. I'm using bind in this article, but volume and tmpfs are valid values as well.
  • source: Can also be shortened to src and defines the source directory or file on the host system.
  • destination: Can also defined as target or shortened to dst and defines the target in the container.
  • readonly: This key doesn't have a value and grants the container read-only access to source.
  • Platform-specific parameters: bind-propagation (Linux) and consistency (macOS), I'll leave those out here because the average user doesn't need them.

Disadvantages of Bind Mounts

Bind mounts are a good fit for environments where a developer changes files in a working directory frequently, but they're just one way to decouple data from containers. The biggest drawback you'll face with bind mounts is that they depend on the directory structure on the host system, which limits the overall portability. Also, multiple users and processes may access the host directory, causing strange and avoidable side effects.

That is why Docker introduced an alternative to bind mounts which is preferable in most other cases: volumes.

💫graph: A library for creating generic graph data structures and modifying, analyzing, and visualizing them.
💫
graph: A library for creating generic graph data structures and modifying, analyzing, and visualizing them.