moby: File mount does not update with changes from host
I have this nginx container, on which I’m mounting a vhost configuration file (indirectly, in fact, I’m using a data volume container). I would like to reload the configuration without stopping the container, with docker-compose kill -s HUP webserver
, but when I change the configuration file on the host, it does not change on the guest, and vice versa. When I restart the container however, the guest takes into account the host changes. Here is an excerpt of my docker-compose.yml :
data:
build: ./docker
volumes:
- .:/srv
- ../symfony-1.4.20:/usr/lib/symfony-1.4
- ./docker/conf/nginx_vhost.conf:/etc/nginx/sites-enabled/app.conf
- .home-developer:/home/developer
- $SSH_AUTH_SOCK:/tmp/agent.sock
webserver:
image: greg0ire/nginx
volumes_from:
- data
env_file:
- ./docker-compose.env
environment:
- DNSDOCK_IMAGE=web
links:
- appserver
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 35
- Comments: 69 (14 by maintainers)
Commits related to this issue
- Workaround of moby/moby#15793 Reference: https://github.com/moby/moby/issues/15793 — committed to femiwiki/docker-mediawiki by simnalamburt 5 years ago
- Mount /etc/faketimerc in the development backend container When a backend with libfaketime installed is used, this can be used to modify the apparent flow of time inside the container. NB: using a f... — committed to wsi-cogs/deploy by sersorrel 5 years ago
- Debug, mauvais transfert du dossier study. Supression de l'ancien bind-mount: https://github.com/moby/moby/issues/15793. — committed to pierremancini/cbioportal-import by pierremancini 6 years ago
- Vim: https://stackoverflow.com/a/15317146/128351 and https://github.com/moby/moby/issues/15793#issuecomment-135411504 — committed to Overbryd/dotfiles by Overbryd 4 years ago
- Refactor .env file setup Volume-mounting individual files is unreliable due to limitations with the way Docker handles inode changes. If editing a file creates a new inode, then those changes will un... — committed to hemberger/smr by hemberger 3 years ago
- zshrc: add quotes and add update nvim/init.vim nvim: * Use grubvox * Create mapping to edit files in place when saving. (By default, vim/neovim create a new file when the opened file is saved and t... — committed to chibby0ne/dotfiles by chibby0ne 2 years ago
- Vim: https://stackoverflow.com/a/15317146/128351 and https://github.com/moby/moby/issues/15793#issuecomment-135411504 — committed to Overbryd/dotfiles by Overbryd 4 years ago
I bet I know what’s happening here…
If you are using some editor like vim, when you save the file it does not save the file directly, rather it creates a new file and copies it into place. This breaks the bind-mount, which is based on inode. Since saving the file effectively changes the inode, changes will not propagate into the container. When the container is restarted the new inode. If you edit the file in place you should see changes propagate.
This is a known limitation of file-mounts and is not fixable.
Does this accurately describe the issue?
I made some tests @greg0ire, and this is the result.
With or without
set noswapfile
the inode changes, everytime the file is saved, but I made a little research how to make vim don’t change the inode of a file. The result was to useset backupcopy=yes
, I try and the inode don’t change when the file is modified.Thank you guys.
Closing, it’s not really a bug, just how linux works unfortunately.
@OscarOrSomething Mount a dir instead of a file.
Turns out it was the opcache settings in the wordpress image I was using. Adding the below lines to my Dockerfile fixed the problem for me (no problems in an hour). Now the files are showing in the container and when previewing with apache.
After reading this, I guess if I type
set noswapfile
, I might be able to continue using vim. Maybe Sublime Text has a similar option ?@cpuguy83 I am mounting a dir.
After some googling, Sublime text has
atomic_save
instead so Adding"atomic_save": false
to user preferences worked (After a restart). Thanks @greg0ireTurning off sendfile off for Nginx solved this issue for me. Just put this in your vhost conf:
The equivalent for Apache it is “EnableSendfile off”. See https://abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile/ for reference.
have the same problem
i change for this and it work
i think the reason is
These are not issues with Docker. Mounting individual files is tricky. A file path and a file inode are different things.
A file path is more akin to a git tag where as an inode is like a commit hash. Just like a git tag can be changed to point to a different hash, so can a file path point to a new inode. A commit hash is definite, it doesn’t change, likewise for an inode. So, file paths are just references to an inode. These references can and do change depending on the actions you perform (e.g.
mv /foo /bar
defeferences/foo
from the underlying inode and creates a new reference/bar
to that same inode)When you bind mount a path (file or dir), you are mounting an inode to a new location (kind of like creating a new git tag pointing to the same commit hash).
If you do something like move a bind-mounted dir to a new location, and then replace it with another dir, the bind-mount will follow the original dir, same for files. With many editors, the editor will write to a temp file, then replace the real file with the temp file on save, in effect dereferencing the inode (like pointing a git tag to a different commit) from the given path and a new inode taking the reference. Since mounts follow the inode, not the path reference, on the host side you are reading/writing to a new inode, on the container side you are reading/writing from the original inode.
It’s how the linux kernel works 🤷♂️ you can try it on your host (on a linux machine, but probably works on macOS as well);
Thanks to @greg0ire and @cpuguy83 . It’s always a relief to me when some mysterious technical glitch that happened to me has a decent reason.
Unfortunately I don’t think there’s a way to make bind-mounting single files work; mounting a folder is really the only solution if the editor does a “move old, and write updated file to old location”
@cpuguy83:
docker run ... -d /home/user/data/something.txt:/data/something.txt
echo "new content" > /home/user/data/something2.txt
mv something2.txt something.txt
Then the inode table have one row less, so it is detectable. Docker already knows the original path (
/home/user/data/something.txt
), also knows the inside path (/var/lib/docker/volume/.../something.txt
), so he can check and remount the new path.Or file path in volumes should be disabled. It is more trouble than good.
This thread is amazing. I was running into this problem and effectively, yes, I was using vim and yes,
set backupcopy=yes
makes things work as hoped. Thanks for resolving my problem users of github 😊Ouch. So this is why we sometimes have to reload our containers inexplicably. This is a dreadful bug, I must say that I don’t really agree with it being closed. When explicitly volume binding a file name I would expect changes to the file with that name to be reflected in the container without the need to have knowledge about the intricacies of the file system.
Is it really impossible to monitor for example the modified time stamp and update the inode reference accordingly?
My workaround was to
ln /tmp/foo path/to/foo
the extra reference count on the inode means it doesn’t change when the editor writes the new file.I had the same problem on Windows 10 after updating Docker to 2.1.* To solve it I rearrange my app structure.
I think mapping whole directory
./
in combination with other mappings caused problem.Yesterday I faced this issue when using Docker HostManager -
/etc/hosts
wasn’t updated though DHM container was working. Yes, I usevim
for simple editing and didn’t have idea that swapping files on save causes inode change and Docker file mount desynchronization. I’ll sum up what I did:~/.vimrc
with:source ~/.vimrc
to~/.config/nvim/init.vim
/etc/hosts
so I don’t need to usesudo
and my own.vimrc
is loaded:sudo setfacl -m u:your-user:rwX /etc/hosts
Now, when I edit
/etc/hosts
manually, it is instantly propagated to DHM container and everything works like it should. Thanks all for your comments, it helped me to find real issue 😃References:
If someone is facing the same issue with Docker PHP image, another helpful thing is to disable any PHP cache extension e.g. opcache. memcache, etc
Dazed and confused… saved my afternoon
Thank you! My Volume Setup was the follow:
My goal was to debug the script, after the container was created
so I changed the script and I executed it inside the docker container. nothing “new” happend.
I moved the startup script to a “startup” folder and changed the docker-compose.yml
I executed the script again inside the docker container and my changes w.ere recognized.
PS: my english sucks 😄
@greg0ire I try use
set noswapfile
, but nothing change… Isn’t possible use vim with volumes?Is there any better solutions… I’m using VSCode facing same issue. Mounting folder instead of a single file is not a good idea.
@klaslo docker does not monitor anything.in this regard. It relies on the kernel, and the kernel does not support this. The right place to “fix” this is the kernel. We could introduce hacks, but I’m not sure it’s worth it, at least not right now.
I have Docker for Mac. Adding a new file with code works instantly. Yay, right? When I modify the file with
Atom
text editor, the changes take around a minute.The image I’m using is the official Wordpress image, even if Docker for Mac fixes the
inode
stuff, it wouldn’t seem like it. Why? Because there seems to be a caching of files as @moneal pointed out earlier.For example make a new file:
I’d hate to run the following, removing some intended functionality for production servers, is there a work around for local development, a hook or something that only runs locally.
RUN rm -rf /usr/local/etc/php/conf.d/opcache-recommended.ini
I ended making a file in
mu-plugins/_.php
with the following codeFile modifications seem to be appearing instantly from what I can tell. This is probably not efficient or desired, but I’ll just end up adding it to the
git-ignore
. Hope this helps.k8s isn’t fully compatible with Docker 1.11 yet, also k8s does some things outside of the “api” for Docker (direct access to files in
/var/lib/docker
, working around standard networking in docker), which is, well, not always the most reliable approach.@OscarOrSomething I suspect that’s because VirtualBox shared folders don’t support inotify; https://www.virtualbox.org/ticket/10660
I just restarted my container, used nano to do the editing and it works! Thanks a lot. Feel free to close this, I am not sure if it should be considered as a bug or not.