Files within Docker bind mount directory not updating
Asked Answered
F

2

12

I am using docker bind mount to map the host /dev/serial/ folder generated by Ubuntu (which contains identifying symlinks to serial devices such as /dev/ttyUSB0). The full docker container run command I am using is

docker run -d --restart always --privileged=true -v /dev/serial:/dev/serial DOCKER_IMAGE_NAME

This works fine at first run, however if the serial device is disconnected and reconnected, the symlinks are recreated. This change does not propagate into the docker container and instead the docker container finds an empty /dev/serial folder. I tested manually creating a file on the host and within the docker container in this directory as well, and strangely the change on one was not updated in the other in both cases.

The volume is shown as

{
    "Type": "bind",
    "Source": "/dev/serial",
    "Destination": "/dev/serial",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
}

EDIT: Ubuntu creates the symlinks within two directories, by-path and by-id underneath the /dev/serial folder.

Franchot answered 29/11, 2018 at 21:36 Comment(1)
In my case the mounthing is shown perfectly ie Source and Destination are correct but the folder content does not get updated. Restarting Docker finally exposes the files ie Bind mount connection is again established. Note : I am mounting Windows location to a linux containerBeggary
A
24

Bind mounts are based on inodes and when the file is deleted and recreated then the bind-mount is broken. These changes aren't propagated to the bind-mount until a container restart so it picks the new inode.

A solution for this case (files are deleted and recreated) is to mount the parent directory instead, so in your case you can mount using -v /dev:/dev. Of course this will expose /dev to the container so handle it with care.

Ashleaashlee answered 29/11, 2018 at 21:46 Comment(5)
Thanks for the reply. I didn't realize that when the device is unplugged Ubuntu would not only remove the symlinks in the subdirectories under /dev/serial but also the /dev/serial directory itself. Mounting /dev works well.Franchot
Even if I mount the directory where the file exists rather than the file itself, the file still does not receive new data from the container if the file is deleted and recreated while the container is running. It may still be an "inode" issue, but the solution presented does not work.Brenner
@KenRoy how did you solve that?Diactinic
@anatol, instead of letting the host delete the file that is mounted by a container, I set it so the host only empties the file. So the file's inode never changes.Brenner
This doesn't work when I want to mount a network drive which on the container is on /mnt/webdav and on host I'm using bind mount using rshared. Tried both /mnt/webdav and /mnt too. on /mnt it says /sbin/mount.davfs: can't evaluate path of mount point (null) I also tested without bind, only volume too.Mightily
B
4

The issue exists with Previous versions of Docker. The reason for the same has been clearly explained by Sebastian Van

This looks like a race condition; the problem here is that, when using the -v : option, docker will automatically create if the path does not exist. This functionality was marked for deprecation at some point (exactly because of these issues), but it was considered too much of a breaking change to change (see moby/moby#21666, and issues linked from that issue).

Docker for Windows (when running Linux containers) runs the docker daemon in a VM. Files/directories shared from your local (Windows) machine are shared with the VM using a shared mount, and I suspect that mount is not yet present when the container is started.

Because of that, the %USERPROFILE%/docker_shared directory is not found inside the VM, so the daemon creates that path (as an empty directory). Later, when the shared mount (from the Windows host) is present, it's mounted "on top" of the %USERPROFILE% directory inside the VM, but at that point, the container is already started.

Restarting (docker stop, docker start) resolves the situation because at that point, the shared mount is available, and the container will mount the correct path.

follow the Thread: https://github.com/docker/for-win/issues/1192 for better understanding. The issue was resolved in the Docker version 2.0.4.0 (Edge Channel) and later in the stable release.

Beggary answered 25/9, 2019 at 11:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.