情景
出于某种目的,docker容器挂在了外部的文件,而且期望当外部文件发生变化的时候,docker容器对应的文件也发生变化。
难道本来不是这样的吗?是也不是:
是: echo “append info” >>/the/file 立即反应到docker容器内部了
不是: 通过vim编辑,添加一行,docker容器内部文件没有变化
分析: 应该是echo和vim有不同
当不知道的时候,结果就是: 有时候可以,有时候不可以,恶心不恶心?
放狗搜索,这里说的详细: https://github.com/docker/docker/issues/15793
总结一下:
- docker (或者说linux mount)挂卷是基于inode的
- echo 是在原文件基础上修改文件的,没有改变文件的inode
- vim 编辑的时候改变了文件的inode; (上面文章有说,可以通过 set noswapfile来禁用此特性,测试不好使,字面来看也不太是这么回事儿,实际测试应如此设置: set backupcopy=yes)
- 其他编辑器也可能改变inode,有些也可以设置不改变inode
- sed 编辑文件默认也是修改inode的,可以使用-c选项避免inode发生变化
有解决办法吗?
只要想办法确保inode不变即可,如: 编辑文件的时候,先copy走,编辑完再cat 到原文件中。
什么? 你使用vim修改挂载的文件之后,docker容器中的文件立刻就变化了?
先确认下该文件的inode是否变化了(我不想去证明vim修改文件肯定会导致inode发生变化)
还有别的解决办法吗?
- 请确认必须挂在文件而不是也可以挂在目录。挂载目录的话,docker内外是完全同步的
- 如果挂载目录的话,目录中的软连接只能在挂载的目录内有效,如果软链的是其它目录的文件,则容器内外是不同的
关于挂载目录
如果容器内挂载了宿主机目录/home/phpor/test 到容器内部 /test , 现在创建目录 /home/phpor/test/taoyi ;然后在另一个终端容器进入容器/test/taoyi 目录, 这时候,如果宿主机上mv /home/phpor/test/taoyi /home/phpor/taoyi , 然后 创建文件 /home/phpor/taoyi/file ; 这时候,在另一个终端下对于原本已经进入 /test/taoyi 的回话将可以看到file文件