Docker – Mount Volumes from Device Instead of Directory

dockerdocker-compose

I'd like to setup a docker service (docker-compose) on a Linux host with a container mounting an entire [removable] physical hard drive as a docker volume.

I know that it's trivial to setup bind mounts in docker-compose and I can manually mount the drive on the host. That approach does work, but it involves manual steps with an opportunity for human error. Bad things happen when this service starts with a blank directory on the host's drive root partition. Worse things happen if the drive is unplugged while still mounted.

What I'd like to do is have docker mount the device directly as a volume. This would have the advantage of fewer / simpler manual steps and a failsafe that if the drive was missing the service would fail to startup. This also would ensure the drive us unmounted when the service is stopped.

Given that volumes are basically just OS mounts, it feels like this should be simple, but numerous searches through the documentation and I'm still no further forward.

Best Answer

On a linux docker host this is possible by first creating named volume with a local driver.

The named volume is just a specification for what to mount when the container starts so the device does not need to be plugged in when the volume is created.

From docker you first create a named volume. Let's say the device I want to mount is an ext4 drive and will always appear as /dev/disk/by-uuid/d28c6d3a-461e-4d7d-8737-40e56e8f384a:

# Create "my-volume"
docker volume create --driver=local --opt type=ext4 --opt device=/dev/disk/by-uuid/d28c6d3a-461e-4d7d-8737-40e56e8f384a my-volume
# Run a container with it mounted to a path.
docker run -v my-volume:/my-volume --rm -it alpine sh

Note: Under linux device names can often change. So it's not a good idea to use something like /dev/sdb1 as you can't guarantee it will always be named sdb1. In the example above I've used the uuid to make sure the right device is always mounted.

Related Topic