V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BIAOXYZ
V2EX  ›  Docker

请教一个 docker-compose 挂载文件的奇怪问题

  •  
  •   BIAOXYZ · 54 天前 · 1347 次点击
    这是一个创建于 54 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个老项目环境(涉及内部好几个代码仓库)不好搭,大家都是用 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 看过,这个命令的结果是符合预期的。所以真的没招了,请大家帮忙看看,感谢!!!

    26 条回复
    shineshane
        1
    shineshane  
       54 天前   ❤️ 1
    task_manager.pyuser_manager.py 的权限完全一致么?
    BIAOXYZ
        2
    BIAOXYZ  
    OP
       54 天前
    @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
    ```
    shineshane
        3
    shineshane  
       54 天前   ❤️ 1
    @BIAOXYZ 宿主机上和容器内都完全一致么?
    BIAOXYZ
        4
    BIAOXYZ  
    OP
       54 天前
    @shineshane 我觉得最想不通的一点就是:我现在就算把 docker-compose.yml 改一下,把 task_manager.py 那行注释掉,docker-compose down; docker-compose up -d ,然后在 docker-compose config 看下确实修改生效了。这样做了之后发现还是 task_manager.py 在宿主机修改能同步进去容器里。。。就有点束手无策,感觉还是哪里有缓存?但是不知道在哪。
    BIAOXYZ
        5
    BIAOXYZ  
    OP
       54 天前
    @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
    ```
    shineshane
        6
    shineshane  
       54 天前   ❤️ 1
    @BIAOXYZ #4 你说的这点太神奇了,我确实没有遇到过这种情况。你可以修改宿主机上的 task_manager.py 文件后(比如加一行注释)再重启,看容器内的文件是否有相应修改,以验证挂是否正确。

    ---

    我之前也遇到过一个很奇怪的问题,跟宿主机上的文件权限有关,但是我不清楚是为什么。你可以尝试用权限更大的用户启动 compose ,比如 root ,看下这时候是否能正常同步内容。
    yinmin
        7
    yinmin  
       54 天前 via iPhone   ❤️ 1
    大概率是你修改的 docker-compose.yml 不对应你操作的容器。你把 docker-compose.yml down 下来,然后再试试容器还在不。
    yinmin
        8
    yinmin  
       54 天前 via iPhone   ❤️ 1
    volumes 是引用不是同步,没缓存概念一说
    shineshane
        9
    shineshane  
       54 天前   ❤️ 1
    @yinmin #7 OP 的现象确实像你描述的这种场景
    fitme
        10
    fitme  
       54 天前   ❤️ 1
    docker 挂载文件通过 vim 这种工具修改后 inode 变了,所以你看到的文件名一样,但已经不是同一个文件了。所以你重启重新挂载就好了
    cheng6563
        11
    cheng6563  
       54 天前   ❤️ 1
    dockerd 如果被 selinux 限制的话也会出现奇怪的挂载问题,检查下吧。最常见的原因就是用 ubuntu 的 snap 装了 docker
    BIAOXYZ
        12
    BIAOXYZ  
    OP
       54 天前
    @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 看的结果也是没挂载任何卷了。

    简直有点崩溃了- -不过还是感谢您的回复。谢谢🙏
    BIAOXYZ
        13
    BIAOXYZ  
    OP
       54 天前
    @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 ,看这个命令的结果修改是生效的。

    不过我感觉应该就是类似您提到的原因,只是我确实想不到疏漏还可能在哪里了。
    newaccount
        14
    newaccount  
       54 天前   ❤️ 1
    常见的坑,使用 volume 挂载的时候,请挂载文件夹而不是文件,否则 inode 一变,各种想不通的问题就来了
    BIAOXYZ
        15
    BIAOXYZ  
    OP
       54 天前
    @fitme 我是 vs code 连接到远程虚拟机上改的 yml 文件,改完后 docker-compose down 然后 docker-compose up -d 执行了。也 docker-compose config 看了重新执行后的配置,看起来改动是生效了的。有点郁闷
    BIAOXYZ
        16
    BIAOXYZ  
    OP
       54 天前
    @cheng6563 请问下这个怎么检查呢?看起来是有个文件能挂载,其他的目录或文件不能;然后更神奇的是就算我修改配置不再挂载这个文件,重启后这个文件还是挂载的。。。。。。另外 docker 不是 snap 装的,直接按官方文档 apt 装的
    BIAOXYZ
        17
    BIAOXYZ  
    OP
       54 天前
    @fitme 突然反应过来,您这里的重启是指重启虚拟机?因为涉及 inode 了。我刚才理解成重启 docker-compose 服务了。
    BIAOXYZ
        18
    BIAOXYZ  
    OP
       54 天前
    @newaccount 好的,谢谢回答。我在当前情况下试过挂载目录,也还是不行的(确实发生过更改目录名字)。我怀疑是要重启虚拟机才行。
    fitme
        19
    fitme  
       54 天前   ❤️ 1
    @BIAOXYZ 我说的就是容器,如果你通过 down up 那就重建服务了,和我说的不是一回事了。如果容器服务重启过那确实诡异,你可以再排查看看
    BIAOXYZ
        20
    BIAOXYZ  
    OP
       54 天前
    @fitme 重启过,而且容器都停止后还确保了 1.所有容器都删干净了,只留下了镜像; 2.所有 volume 也都删干净了。然后再次启动 docker-compose ,还是一样的奇怪现象:task_manager.py 在宿主机修改能同步到容器里(即使我不再挂载它);其他的文件在宿主机修改无法同步进去。

    我打算重启下虚拟机再试试。
    fitme
        21
    fitme  
       54 天前
    @BIAOXYZ 不是,你现在描述的我感觉不清晰,你是想解决在不重启容器的情况下,通过修改宿主机文件同步到容器里面? 还是说你在修改了宿主机文件后,down up 后(相当于容器重建)宿主机修改的位置容器还是没变?
    yinmin
        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
    BIAOXYZ
        23
    BIAOXYZ  
    OP
       54 天前
    @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
    ```
    这次就可以了,感谢~
    BIAOXYZ
        24
    BIAOXYZ  
    OP
       54 天前
    @yinmin 好的,谢谢~这个之前简单试过,没深入,回头再试试。
    zljklang
        25
    zljklang  
       54 天前   ❤️ 1
    ${REPO_PATH}/managers/:/home/tiger/managers/ 直接映射目录试试
    cosette
        26
    cosette  
       54 天前
    不管是挂载文件还是文件夹,在宿主机上修改文件后,最好 docker restart 一下,如果是修改了 docker-compose.yml 或者相关的.env 文件的内容,则只需要 docker compose up -d 就行了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1160 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:50 · PVG 07:50 · LAX 16:50 · JFK 19:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.