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.
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
: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 namedsdb1
. In the example above I've used the uuid to make sure the right device is always mounted.Fordocker
/docker-compose
mounting a device into a container only is not a supported use case and thus there is no straight forward way to do this (at least as far as I know).Update: actually this is supported by the
local
volume driver, see the accepted answer. This answer is just a possible workaround.But you could pass the block device through to the container with the
--device
flag ofdocker run
(or thedevices
attribute fordocker-compose
respectively) and manually mount the device in your container - e.g. with an appropriate entrypoint script.Be aware that mounting a block device requires enhanced capabilities that are normally dropped for a new container, so you also need to add the
CAP_SYS_ADMIN
capability, like this:(for
docker-compose
see thecap_add
attribute)You can then - either manually or in a script/custom entrypoint - mount the disk within the container:
This approach would only require you to add the mounting of the device to your container but would then meet all your other requirements:
mount
!)docker-compose
To avoid problems with changing names of the device when un-/plugging it you can use one of the symlinks created for it in
/dev/disk/by-label/
or/dev/disk/by-uuid/
.