Touching a sub-mounted directory on the host unmounts the submount in the container


I’m trying something that I expected to be pretty straightforward but have run into a problem I don’t know the answer to.

I’m running a dev container (the same as my CI container) to be able to have repeatable builds locally during development. I also want it to be possible to run build commands locally on my Mac and have that work too. The sticking point right now is node_modules. I want the node_modules on my Mac and the node_modules in the container to be completely separate so that I don’t run into build issues. Here is the command I’m using to start my dev container:

    docker run -d \
        --name $NAME  \
        -v /var/run/docker.sock:/var/run/docker.sock \
        --mount type=volume,source=code-node,destination=/code/node_modules/ \
        --mount type=bind,source="$(pwd)",destination=/code \
        -w /code \
        ci-container \
        tail -f /dev/null

This works as I’d expect, at first. I can run web pack in the container and it will build the frontend correctly without messing with the Mac node_modules.

However, if on my Mac I run touch node_modules (which gulp seems to do) then the mounted volume disappears from the container, and running docker exec ls node_modules shows that node_modules in the container has become the same as the one on my Mac.

What’s going on? How can I have the behavior I want? Will it behave any differently if run via docker-compose? I’m at a loss for why my volume disappears in this way.

Is there a command to get docker to re-mount the volume correctly once it’s disappeared?

Update: touching node_modules appears to unmount the sub-mount. Doesn’t matter if it’s a volume mount or another bind mount.

I’d accept a workaround where I remount the device in linux, but I’m not sure that’s possible yet.

Lets assume for a minute that you don’t break the “mount a named volume into a folder” logic by placing a file at the target position of the mount, how would you make sure the volumes are mounted in the correct order?

Thus, making /code/node_modules not beeing mounted first, which would be completely replaced by mounting /code afterwards? It would work if the target /code is mounted before the target /code/node_modules. Though, I am not sure if there is guarantied order for mounts.

This seems to be the accepted solution for doing dev in docker. The sub mount always appears correctly until node_modules is touched.

But maybe the real solution is figuring out somewhere else to put node_modules.