Docker 挂载文件,宿主机修改后容器里文件没有修改
问题
使用 Docker Volumes 时,有时需要挂载一个宿主机目录或者文件,提供数据可持续或者容器内部服务配置文件。
使用命令 docker run -it --rm -v /root/test.txt:/root/test.txt debian:10 bash 挂载文件(test.txt 默认权限 644)时,通过 vim 修改宿主 test.txt 文件,但是容器中 test.txt 没有修改。这是为什么?
因为vim修改后,原来的文件已经被删除,这个"文件名“对应是新文件,但是容器还是会一直记录以前的文件,所以容器看到的文件没有同步更改。
分析:简述 vi 或者 vim 修改文件过程
Linux 默认情况下,vim为了防止在你修改文件的过程中,由于磁盘或者系统出现问题而导致当前被修改的文件的损坏,它做了类似如下逻辑:
1、复制出一个需要修改文件的副本,命名为在原来文件的基础上增加 ".swp" 后缀以及 "." 前缀。
2、修改内容保存到有 .swp 后缀的文件,并 flush 到磁盘
3、执行 :wq 就会交换原文件和 swp 文件的名称
4、删除临时 swp 文件
从上面可以看出,原来的文件已经被删除
测试
Linux中,证明文件是否相同的根本途径是,判断其 inode,如果两个文件的inode相同,两个文件必定为同一文件
1、在宿主机上创建一个 /root/test.txt 文件,使用命令 stat 查看 inode 值,如下图:

2、使用命令 docker run -it --rm -v /root/test.txt:/root/test.txt debian:10 bash 临时启动一个容器,把宿主机文件 /root/test.txt 挂载到容器中。
3、另开一个终端,使用 vi 命令修改 /root/test.txt 文件,编辑完后保存,再次使用 stat 命令查看 /root/test.txt 文件 inode 值。从下图已经发现,inode 值已经改变。

4、登陆容器查看 /root/test.txt 文件 inode 值。如下图,inode 值还是 vi 修改前的值。而不是修改后的值。这也就解释为什么宿主机上修改了文件而容器中文件没有更新的原因。因为容器与宿主机使用的不是同一个文件。

解决办法
- 使用 echo 等修改文件,替换使用 vim 或者 vi
- 挂载目录,不要挂载文件

浙公网安备 33010602011771号