Home > database >  Reflect changes in read-only docker volume to the container?
Reflect changes in read-only docker volume to the container?

Time:07-11

I have a config file being injected into Docker at runtime using a read-only volume. Thus the container cannot change the contents of the config file, but the host can. The idea is to send a SIGHUB to the process inside the container to reload any config changes. However, Docker seems unable to detect any changes to the config file, and seems to see a frozen snapshot of the file as-of the time when the container started.

Is this expected behaviour for Docker?

CodePudding user response:

A bind mount, which docker uses for host volumes, is mapping an inode to a second location. An inode is a pointer to a file or directory in Linux. And the standard process for most editors is not to modify a file in place, but to create a temporary file with a new inode, and then replace the existing file with one that has a new inode. This avoids corruption where a crash would leave the file in a partially written state. You should see this happening with an ls -i on the file.

For a bind mount, this means you still have the bind mount to the original inode even after the host sees the file with new content. You can solve that by either:

  • bind mount the entire folder instead of only the file
  • recreate the container to pickup the new change (a restart may work too)
  • edit the file without changing the inode

For the latter, commands like echo new line >>file or cat tmp-file >file will keep the same inode on file. You may find settings for your editor too.

CodePudding user response:

Either your question is unclear to me; or your docker installation has a bug.

I think you want to do this:

  • Start a container, binding a host file into the container.
  • Be able to edit the file inside the container, and reflect those edits in the "host version" of the file.

On my machine (bog standard Docker installation), the following command line achieves exactly what you're asking:

docker run -v /tmp/host.txt:/tmp/container.txt -it --rm alpine sh

I can then edit either /tmp/host.txt on the host, or /tmp/container.txt within the container, and the changes are immediately reflected on the other side. In fact, technically, the two files physically are the same, just hidden behind layers and layers of the "onion" magic of Docker.

Adding :ro to the argument of -v does as expected - it makes the file read-only, and if I try to edit it anyways, the editor shows the message "read-only filesystem", as it should be.

Note that this style of -v is a bind mount in the parlance of Docker (in the case of volume mounts there is no "host version" of the mounted directory/files, so none of this applies).

If nothing of this helps please clarify your question.

  • Related