Search code examples
dockerdocker-volume

Why is /host_mt/ required when using bind mount volumes in Windows


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:

  1. Create the volume: docker volume create --opt type=none --opt device=%(pwd)/data_dir --opt o=bind --name data_volume
  2. Runt a container with the 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).


Solution

  • 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.