【问题标题】:Why does docker-compose create an empty host folder when mounting named volume?为什么 docker-compose 在挂载命名卷时会创建一个空的主机文件夹?
【发布时间】:2019-05-24 18:55:48
【问题描述】:

我的docker-compose.yml 文件中有以下内容:

volumes:
    - .:/var/www/app
    - my_modules:/var/www/app/node_modules

我这样做是因为我的主机上没有node_modules,并且所有内容都安装在映像中并且位于/var/www/app/node_modules

对此我有两个问题:

  1. 在我的主机中创建了一个名为 node_modules 的空文件夹。如果我在.yml 文件的列表中添加另一个卷(命名或匿名),它将显示在包含我的.yml 文件的同一文件夹中的主机目录中。从this 的答案来看,这似乎与这两个映射同时进行的事实有关。但是,为什么我的主机上的文件夹是空的?它不应该是 a) 包含命名卷中的文件还是 b) 根本不显示在主机上?

  2. Docker 如何知道在初始化卷时检查底层的/var/www/app/node_modules 而不是仅仅说“哦,node_modules 不存在”(因为我假设主机绑定挂载发生在命名卷被初始化之前,因此/var/www/app 不应再有一个名为node_modules 的文件夹。当我在我的主机上创建一个示例node_modules 文件夹和一个新卷同时保留my_modules:/var/www/app/node_modules 时,它似乎甚至可以工作——它似乎仍然使用图像中的node_modules,而不是主机(这不是我所期望的,虽然不是不需要的)。

【问题讨论】:

    标签: docker docker-compose dockerfile


    【解决方案1】:

    作为一个实现细节,Docker 在挂载卷时实际上使用了 Linux 内核文件系统挂载工具。要挂载一个卷,它必须挂载到一个目录,所以如果挂载目标不存在,它会创建一个新的空目录作为挂载点。如果挂载点本身位于已挂载的卷中,您将看到创建了空目录,但不会回显挂载。

    (如果您在 Linux 主机上,请尝试在容器运行时在 shell 中运行 mount。)

    即:

    • /container_root/app 是绑定到 /host_path/app 的挂载;它们是相同的基础文件。
    • mkdir /container_root/app/node_modules 也会创建 /host_path/app/node_modules
    • /container_root/app/node_modules 上安装其他内容不会导致在/host_path/app/node_modules 上安装任何内容。
    • ...留下一个空的/host_path/app/node_modules 目录。

    The first time you start a container,只有这样,如果您将空卷挂载到容器中,映像中的内容才会被复制到卷中。你告诉 Docker 这个目录包含关键的 data 需要比容器的生命周期更长的时间。这不是一个神奇的“不要使用主机目录卷”旋钮,如果您更改package.json 文件之类的操作,Docker 将不会更新此卷的内容。

    【讨论】:

    • 非常感谢!似乎没有意义的一件事是,如果我运行docker-compose up -d,然后运行docker-compose stop,从主机中删除node_modules,然后运行docker-compose up -d,当我ls 时,我看到空的node_modules 文件夹再次。我认为这不会发生,因为容器没有被重新创建。因此,如果容器没有被重新创建并且它只是从停止状态再次启动,我认为该文件夹不会在主机中再次创建。
    • 我创建了一个后续问题here
    猜你喜欢
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    相关资源
    最近更新 更多