有个老项目环境(涉及内部好几个代码仓库)不好搭,大家都是用 docker-compose 启动,然后挂载宿主机的文件到容器里。我遇到了一个奇怪的问题,我的 docker-compose.yml 里某个容器的挂载相关配置是这么写的:
volumes:
# - ${REPO_PATH}/managers:/home/tiger/managers
- ${REPO_PATH}/managers/task_manager.py:/home/tiger/managers/task_manager.py
- ${REPO_PATH}/managers/user_manager.py:/home/tiger/managers/user_manager.py
结果 task_manager.py 在宿主机修改就能同步进去容器里,user_manager.py 在宿主机修改就死活不能同步进去。问了 chatgpt ,给的方法都试了也不行。容器都删过一遍了,所有的 volume 都清空过了。再试也还是不行。
更神奇的是,我就算把 task_manager.py 那一行注释掉,task_manager.py 的修改照样能同步——仅从这一点看是不是哪里还有缓存之类的没清理?
但是我 docker-compose config 看过,这个命令的结果是符合预期的。所以真的没招了,请大家帮忙看看,感谢!!!
![]() |
1
shineshane 54 天前 ![]() task_manager.py 和 user_manager.py 的权限完全一致么?
|
![]() |
2
BIAOXYZ OP @shineshane 是一致的。
``` $ ls -la total 60 drwxr-xr-x 2 tiger tiger 4096 Jul 15 11:27 . drwxr-xr-x 14 tiger tiger 4096 Jul 13 21:46 .. -rw-r--r-- 1 tiger tiger 64 Jul 13 21:46 base_manager.py -rw-r--r-- 1 tiger tiger 10582 Jul 15 14:30 data_manager.py -rw-r--r-- 1 tiger tiger 31822 Jul 15 14:53 task_manager.py -rw-r--r-- 1 tiger tiger 3101 Jul 15 14:36 user_manager.py ``` |
![]() |
3
shineshane 54 天前 ![]() @BIAOXYZ 宿主机上和容器内都完全一致么?
|
![]() |
4
BIAOXYZ OP @shineshane 我觉得最想不通的一点就是:我现在就算把 docker-compose.yml 改一下,把 task_manager.py 那行注释掉,docker-compose down; docker-compose up -d ,然后在 docker-compose config 看下确实修改生效了。这样做了之后发现还是 task_manager.py 在宿主机修改能同步进去容器里。。。就有点束手无策,感觉还是哪里有缓存?但是不知道在哪。
|
![]() |
5
BIAOXYZ OP @shineshane 是的,这个是容器里的:
``` tiger@170afb795451:~/managers$ ls -la total 68 drwxr-xr-x 1 tiger tiger 4096 Jul 15 14:35 . drwxr-xr-x 1 tiger tiger 4096 Jul 15 14:35 .. -rw-r--r-- 1 tiger tiger 64 Mar 6 15:36 base_manager.py -rw-r--r-- 1 tiger tiger 10532 Mar 6 15:36 data_manager.py drwxr-xr-x 2 tiger tiger 4096 Jul 15 14:35 __pycache__ -rw-r--r-- 1 tiger tiger 31822 Jul 15 14:53 task_manager.py -rw-r--r-- 1 tiger tiger 3052 Mar 6 15:36 user_manager.py ``` |
![]() |
6
shineshane 54 天前 ![]() @BIAOXYZ #4 你说的这点太神奇了,我确实没有遇到过这种情况。你可以修改宿主机上的 task_manager.py 文件后(比如加一行注释)再重启,看容器内的文件是否有相应修改,以验证挂是否正确。
--- 我之前也遇到过一个很奇怪的问题,跟宿主机上的文件权限有关,但是我不清楚是为什么。你可以尝试用权限更大的用户启动 compose ,比如 root ,看下这时候是否能正常同步内容。 |
7
yinmin 54 天前 via iPhone ![]() 大概率是你修改的 docker-compose.yml 不对应你操作的容器。你把 docker-compose.yml down 下来,然后再试试容器还在不。
|
8
yinmin 54 天前 via iPhone ![]() volumes 是引用不是同步,没缓存概念一说
|
![]() |
9
shineshane 54 天前 ![]() @yinmin #7 OP 的现象确实像你描述的这种场景
|
![]() |
10
fitme 54 天前 ![]() docker 挂载文件通过 vim 这种工具修改后 inode 变了,所以你看到的文件名一样,但已经不是同一个文件了。所以你重启重新挂载就好了
|
![]() |
11
cheng6563 54 天前 ![]() dockerd 如果被 selinux 限制的话也会出现奇怪的挂载问题,检查下吧。最常见的原因就是用 ubuntu 的 snap 装了 docker
|
![]() |
12
BIAOXYZ OP @shineshane 对,我也觉得很神奇,神奇到邪门。现在我还能百分百复现:
``` tiger@5a159fe5fe85:~/managers$ head task_manager.py # task_namager compose # task_manager compose112233 # 1233 import json from managers.base_manager import BaseManager from managers.user_manager import UserManager from utils.config import global_config from utils.config_tools import generate_output_path, parse_dsc_db_path tiger@5a159fe5fe85:~/managers$ tiger@5a159fe5fe85:~/managers$ tiger@5a159fe5fe85:~/managers$ # 在宿主机修改一下 tiger@5a159fe5fe85:~/managers$ tiger@5a159fe5fe85:~/managers$ head task_manager.py # task_namager compose # task_manager compose112233 # 123344444444444444444444 import json from managers.base_manager import BaseManager from managers.user_manager import UserManager from utils.config import global_config from utils.config_tools import generate_output_path, parse_dsc_db_path tiger@5a159fe5fe85:~/managers$ ``` 但此时我的 docker-compose 的配置是: ``` # volumes: # - ${JCNC_REPO_PATH}/managers:/home/tiger/managers # - ${JCNC_REPO_PATH}/managers/task_manager.py:/home/tiger/managers/task_manager.py # - ${JCNC_REPO_PATH}/managers/user_manager.py:/home/tiger/managers/user_manager.py ``` 我已经把所有 volume 都注释掉了。执行 docker-compose conifg 看的结果也是没挂载任何卷了。 简直有点崩溃了- -不过还是感谢您的回复。谢谢🙏 |
![]() |
13
BIAOXYZ OP @yinmin 您指的是 docker-compose down 然后 docker-compose up -d 吗?我这样做了,甚至还 docker rm $(docker ps -a) 以及 docker volume prune 把除了镜像和网络以外的都清理了下,还是不行。
其实我也怀疑是我修改的 docker-compose.yml 对不上,但是我每次修改后,会进入到 docker-compose yml 所在的目录,执行下 docker-compose config ,看这个命令的结果修改是生效的。 不过我感觉应该就是类似您提到的原因,只是我确实想不到疏漏还可能在哪里了。 |
![]() |
14
newaccount 54 天前 ![]() 常见的坑,使用 volume 挂载的时候,请挂载文件夹而不是文件,否则 inode 一变,各种想不通的问题就来了
|
![]() |
15
BIAOXYZ OP @fitme 我是 vs code 连接到远程虚拟机上改的 yml 文件,改完后 docker-compose down 然后 docker-compose up -d 执行了。也 docker-compose config 看了重新执行后的配置,看起来改动是生效了的。有点郁闷
|
![]() |
16
BIAOXYZ OP @cheng6563 请问下这个怎么检查呢?看起来是有个文件能挂载,其他的目录或文件不能;然后更神奇的是就算我修改配置不再挂载这个文件,重启后这个文件还是挂载的。。。。。。另外 docker 不是 snap 装的,直接按官方文档 apt 装的
|
![]() |
18
BIAOXYZ OP @newaccount 好的,谢谢回答。我在当前情况下试过挂载目录,也还是不行的(确实发生过更改目录名字)。我怀疑是要重启虚拟机才行。
|
![]() |
20
BIAOXYZ OP @fitme 重启过,而且容器都停止后还确保了 1.所有容器都删干净了,只留下了镜像; 2.所有 volume 也都删干净了。然后再次启动 docker-compose ,还是一样的奇怪现象:task_manager.py 在宿主机修改能同步到容器里(即使我不再挂载它);其他的文件在宿主机修改无法同步进去。
我打算重启下虚拟机再试试。 |
![]() |
21
fitme 54 天前
@BIAOXYZ 不是,你现在描述的我感觉不清晰,你是想解决在不重启容器的情况下,通过修改宿主机文件同步到容器里面? 还是说你在修改了宿主机文件后,down up 后(相当于容器重建)宿主机修改的位置容器还是没变?
|
22
yinmin 54 天前
如果不是生产环境,就安装 portainer 可视化管理 docker 。
docker run -d --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock:ro -p 9000:9000 -v portainer_data:/data portainer/portainer-ce:sts |
![]() |
23
BIAOXYZ OP @fitme 是后者。但是比较神奇的是我不管怎么改都不行。刚才我重启了一下虚拟机,然后按前面另一位 v 友的回答,只挂载目录,也就是
``` volumes: - ${JCNC_REPO_PATH}/managers:/home/tiger/managers # - ${JCNC_REPO_PATH}/managers/task_manager.py:/home/tiger/managers/task_manager.py # - ${JCNC_REPO_PATH}/managers/user_manager.py:/home/tiger/managers/user_manager.py ``` 这次就可以了,感谢~ |
![]() |
25
zljklang 54 天前 ![]() ${REPO_PATH}/managers/:/home/tiger/managers/ 直接映射目录试试
|
26
cosette 54 天前
不管是挂载文件还是文件夹,在宿主机上修改文件后,最好 docker restart 一下,如果是修改了 docker-compose.yml 或者相关的.env 文件的内容,则只需要 docker compose up -d 就行了。
|