【问题标题】:Docker Compose: volumes without colon (:)Docker Compose:不带冒号 (:) 的卷
【发布时间】:2017-09-12 00:52:59
【问题描述】:

我有一个docker-compose.yml 文件,其中包含以下内容:

volumes:
  - .:/usr/app/
  - /usr/app/node_modules

第一个选项将当前主机目录映射到/usr/app,但是第二个选项有什么作用呢?

【问题讨论】:

  • 感谢谷歌标题,这是第一个结果!

标签: docker docker-compose


【解决方案1】:

[刷新这个答案,因为其他人似乎有类似的问题]

docker中有3种volume:

  • 主机卷:这些映射从主机到具有绑定挂载的容器的路径。它们具有简短的语法/path/on/host:/path/in/container。主机上存在的内容在容器中可见,不会合并文件或从映像初始化,并且 uid/gid 没有得到任何特殊映射,因此您需要注意允许容器 uid/gid 读取和对此位置的写访问权(一个例外是 Docker for Mac with OSXFS)。如果宿主机上的路径不存在,docker会以root创建一个空目录,如果是文件,可以通过这种方式将单个文件挂载到容器中。

  • 命名卷:它们有一个名称,而不是作为源的主机路径。它们具有简短的语法 name:/path/in/container 并且在 compose 文件中,您还需要定义在顶层容器中使用的命名卷。默认情况下,这些也是绑定挂载,但在 /var/lib/docker/volumes 下的 docker 特定目录应该被认为是内部的。但是,可以更改这些默认值以允许 NFS 挂载、挂载磁盘,甚至是您自己的绑定挂载到其他位置。命名卷在 docker 中也有一个特性,当它们是新的或空的并且第一次使用时,docker 在挂载之前将图像中的内容复制到命名卷中。这包括文件、目录、uid/gid 所有者和权限。之后,它们的行为与主机卷相同,卷内的任何内容都会覆盖图像位置。

  • 匿名卷:这些只有容器内的路径。它们采用/path/in/container 的形式,docker 将创建一个默认命名卷,其名称为 guid。它们共享命名卷的行为,将文件存储在 /var/lib/docker/volumes 下,使用映像的内容进行初始化,除了它们有一个随机生成的 guid,它不会告诉您如何使用它们,甚至它们是否被使用。您可以将卷安装在另一个容器中并检查内容,或者您​​可以通过检查每个容器以查找 guid 来找到使用该卷的容器。如果您创建一个带有--rm 标志的容器,匿名卷也会被自动删除。

  • tmpfs:等等,我说的是 3,这是 4?那是因为 tmpfs 不被视为卷,挂载它的语法不同。结果是指向内存文件系统中的空的指针。如果您有不希望保存的临时文件,它们相对较小,并且您需要速度或确保它们不会保存到磁盘,这将非常有用。

在 OP 的情况下:

  • /usr/app从主机挂载,常用于开发
  • /usr/app/node_modules 是从镜像初始化的匿名卷

为什么要这样做?可能是因为您不想修改主机上的 node_modules 目录,特别是如果有特定于平台的数据并且您在 Docker 桌面上运行,主机上的 Mac/Win 和容器中的 Linux。在另一个卷挂载的目录结构中,您想要访问的映像中也可能有数据。

匿名卷有缺点吗?我能想到的两个:

  • 如果/usr/app/node_modules 中有任何您想在未来的容器中重复使用的内容,那么您不太可能找到旧卷。我倾向于认为写入这些的任何数据都可能丢失。

  • 随着时间的推移,您经常会发现主机上的卷充满了 guid,并且不清楚哪些正在使用,哪些可以删除。未使用的匿名卷是 docker 过度使用磁盘的几个原因之一。

有关 docker 卷的更多详细信息,请参阅:https://docs.docker.com/storage/


原答案:

第二个创建一个匿名卷。它将在 docker volume ls 中列出,并带有一个长的唯一 id 而不是名称。如果您更新映像,Docker-compose 将能够重用它,但很容易忘记哪个卷属于那些名称,因此我建议始终为您的卷命名。

【讨论】:

  • @BMitch 如果第二行看起来像some_volume:/usr/app/node_modules,那会“命名”这个卷吗?我看到它列为“container_name_some_volume”(docker volume ls)。
  • 你需要在 compose 文件中定义上面的卷,有一个单独的卷部分与服务处于同一级别。当您使用 compose 文件时,生成的名称将是项目名称后跟卷名称。
【解决方案2】:

为了补充已接受的答案,根据Docker's Knowledge Base,有三种类型的卷:主机匿名命名

  • 主机卷位于 Docker 主机的文件系统中,可以 从容器内访问。卷路径示例:

    /path/on/host:/path/in/container

  • 匿名音量在您希望拥有时很有用 Docker 句柄存储文件的位置。可能很难, 但是,当它是 匿名卷。卷路径示例:

    /path/in/container

  • 命名卷类似于匿名卷。 Docker 管理 在磁盘上创建卷的位置,但你给它一个卷名。卷路径示例:

    name:/path/in/container

您的示例中使用的路径是匿名卷

【讨论】:

    【解决方案3】:

    我在阅读this 教程时遇到了同样的问题,而这些行实际上可能在做什么的答案是这样的:

    如果没有匿名卷 ('/usr/src/app/node_modules'),node_modules 目录实际上会在运行时通过挂载主机目录而消失:
    构建 - node_modules创建目录。
    运行 - 将当前目录复制到容器中,覆盖构建容器时刚刚安装的 node_modules。

    docker-compose.yml 文件:

    version: '3.5'
    
    services:
    
      something-clever:
        container_name: something-clever
        build:
          context: .
          dockerfile: Dockerfile
        volumes:
          - '.:/usr/src/app'
          - '/usr/src/app/node_modules'
        ports:
          - '4200:4200'
    

    【讨论】:

      猜你喜欢
      • 2023-02-17
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 2021-02-02
      相关资源
      最近更新 更多