I have the following situation: I want to create a bind mount that initializes based on the contents of a docker image.
On MacOS I can do the following to accomplish this:
docker volume create --opt type=none --opt device=%(pwd)/data_dir --opt o=bind --name data_volume
docker run -v data_volume:/home
This will create a volume with a bind mount to the directory data in the current working directory and the volume is called data_volume. Running the volume only requires specifying the name of the volume.
On Windows 10 however, I can do the following: docker run -v %cd%/data_dir:/home
. This is equivalent to the MacOS description but not using a volume (ergo it initializes with the empty data_dir
directory). This shows however that Docker understands the current bind mount.
When I create a volume using the steps as described for MacOS I get the following error:
Error response from daemon: failed to mount local volume: mount c:/some-path/data_dir:/var/lib/docker/volumes/data_volume/_data, flags: 0x1000: no such file or directory.
Inspecting the container used by not using a docker volume yields the following settings:
...
"Mounts": [
{
"Type": "bind",
"Source": "/host_mnt/c/some-path/data_dir",
"Destination": "/home,
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...
Therefore if I change the volume to: docker volume create --driver local -o o=bind -o type=none -o device=/host_mnt/c/some-path/data_dir data_volume
It works. Why is on Windows the /host_mnt/
prefix required when creating a volume but not when running a container and mounting a bind directly (without docker volume).
Docker is only built for linux due to its kernel namespaceing. So, when you run a docker container on a windows computer, it actually runs a linux virtual machine that runs that docker container (hence why Hyper-V is required to run docker). The UNIX file paths that linux and mac use are different from the ones that windows uses. On linux and mac, file paths start from /
, while on windows file paths start from a drive (like C:/
). The two different systems are incompatible with each other, so docker puts the C drive at /host_mnt/c
in order to make the systems agree with each other.