My main question is: with docker compose on Docker Desktop with WSL 2, when using a bind mount where the host path is a relative path, where and what is the actual host path on the WSL distro used by the docker desktop backend?
Sections below help understanding the context, what I searched and understood, and detail my questions.
I have a docker compose configuration and a container with an Angular application. The content of the project is located on the Windows file system, and the docker compose uses a bind mount with a relative path.
The container does get the initial content, but it seems to never be updated: no live reload, no updated content when (hard-)refreshing the browser page.
Note that this is with Docker Desktop on Windows, after switching from the Hyper-V backend to the WSL 2 one. With Hyper-V, everything worked as expected, it was just much slower (as they state in the documentation).
I really searched a lot... and got quite mad since I took many paths and always got badly stuck.
docker-desktop-data
which was running: it fails, returning immediately, and the process exit code is just the generic 1
for error. Btw, doing the same for docker-desktop
does work.\\wsl$\docker-desktop-data
. There I could finally see the persisted volumes, but couldn't find any folder that would correspond to the bind mountext4.vhdx
files located under C:\Users\<username>\AppData\Local\Docker\wsl\{data,distro}
. I tried to mount it, but as expected it refused since it was already mounted. However I couldn't find any info about where to see the mounted content. It might by this \\wsl$\docker-desktop[-data]
thing, but no doc, nor any command (I tried PowerShell's Get-VHD
which just told me it's "attached") could tell me how to get that info.And probably a few other things which I don't even remember and that were probably already too far from the initial topic.
I also checked the official Docker documentation pages with no luck finding these details.
My next step would be to read the source code of the backends directly...
The real, pragmatic outcome for me is to be able to have the container interact with the local Windows file system content, instead of what seems to be a copy, which I can't locate.
As a bonus, I would love to understand what paths are involved, and what mechanisms are used to bind all of that (e.g. with the working Hyper-V backend, I expect a Hyper-V specific mechanism to have been used to make it possible for the virtualized docker process to expose a Linux path to the container which eventually was just a sort of hard link / shared folder - conceptually speaking - to the Windows file system folder). So, in docker compose's configuration I see a host <=> container
path mapping, but being on Windows there's really a windows host <=> linux host <=> container
mapping and it's that windows host <=> linux host
mapping which seems to behave differently between Hyper-V and WSL 2, with me being unable to locate the linux host
path.
If all of that could be backed by links to documentations (preferably reference/official) it would make it PERFECT.
But, really, getting a solution to the first point would already be extremely helpful.
So, while I still couldn't find a perfect source of info (like official documentation or even source code), I could find some data which confirms some of the information or hypothesis made earlier.
Remembering that Docker is a tool that builds around core Linux APIs, like other container systems, I started to look at namespaces, and more specifically mount namespaces.
Therefore, on a WSL 2 shell instance on the docker-desktop
distro (wsl -d docker-desktop
), the procedure is as follows:
ps
for that. We'll name that value <pid>
below./proc/<pid>/mountinfo
: you can use cat
for that975 931 8:32 /version-pack-data/community/docker/volumes/portainer_data/_data /data rw,relatime master:3 - ext4 /dev/sdc rw,discard,errors=remount-ro,data=ordered
1092 1070 0:56 /whatever/path/on/the/c/drive /container/path rw,noatime - 9p C:\134 rw,dirsync,aname=drvfs;path=C:\;uid=0;gid=0;metadata;symlinkroot=/mnt/host,mmap,access=client,msize=65536,trans=fd,rfd=8,wfd=8
975 931 8:32 /version-pack-data/community/docker/volumes/portainer_data/_data /data rw,relatime master:3 - ext4 /dev/sdc rw,discard,errors=remount-ro,data=ordered
contains the following relevant information:
/version-pack-data/community/docker/volumes/portainer_data/_data
is the path of the volume data on the Linux host, relatively to:/dev/sdc
, which points to the docker-desktop-data
distro (you can check that using findmnt -S /dev/sdc
, which gives us something like /mnt/host/wsl/docker-desktop-data
)/data
within the container, as configured when creating itSo eventually, it maps /data
to /version-pack-data/community/docker/volumes/portainer_data/_data
on device /dev/sdc
, which can be accessed as well from /mnt/host/wsl/docker-desktop-data/version-pack-data/community/docker/volumes/portainer_data/_data
.
However I suspect the mount namespace to be using the device directly, not its mounted path (which I provided only to "prove" it corresponds to the docker-desktop-data
distro).
1092 1070 0:56 /whatever/path/on/the/c/drive /container/path rw,noatime - 9p C:\134 rw,dirsync,aname=drvfs;path=C:\;uid=0;gid=0;metadata;symlinkroot=/mnt/host,mmap,access=client,msize=65536,trans=fd,rfd=8,wfd=8
:
/container/path
inside the container points to.../whatever/path/on/the/c/drive
on the host, through the filesystem of type...9p
, which contains the following parameters:
path=C:/
: so /whatever/path/on/the/c/drive
is relative to the C:/
Windows drivesymlinkroot=/mnt/host
: that C:/
drive is mounted in /mnt/host
, implicitly under /mnt/host/c
So eventually, the host path is again directly consumed from the filesystem, but it has a correspondence on /mnt/host/c/whatever/path/on/the/c/drive
.
/proc/<pid>/mountinfo - Information about mounts