【发布时间】:2017-09-12 00:52:59
【问题描述】:
我有一个docker-compose.yml 文件,其中包含以下内容:
volumes:
- .:/usr/app/
- /usr/app/node_modules
第一个选项将当前主机目录映射到/usr/app,但是第二个选项有什么作用呢?
【问题讨论】:
-
感谢谷歌标题,这是第一个结果!
标签: docker docker-compose
我有一个docker-compose.yml 文件,其中包含以下内容:
volumes:
- .:/usr/app/
- /usr/app/node_modules
第一个选项将当前主机目录映射到/usr/app,但是第二个选项有什么作用呢?
【问题讨论】:
标签: docker docker-compose
[刷新这个答案,因为其他人似乎有类似的问题]
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 将能够重用它,但很容易忘记哪个卷属于那些名称,因此我建议始终为您的卷命名。
【讨论】:
some_volume:/usr/app/node_modules,那会“命名”这个卷吗?我看到它列为“container_name_some_volume”(docker volume ls)。
为了补充已接受的答案,根据Docker's Knowledge Base,有三种类型的卷:主机、匿名和命名:
主机卷位于 Docker 主机的文件系统中,可以 从容器内访问。卷路径示例:
/path/on/host:/path/in/container
匿名音量在您希望拥有时很有用 Docker 句柄存储文件的位置。可能很难, 但是,当它是 匿名卷。卷路径示例:
/path/in/container
命名卷类似于匿名卷。 Docker 管理 在磁盘上创建卷的位置,但你给它一个卷名。卷路径示例:
name:/path/in/container
您的示例中使用的路径是匿名卷。
【讨论】:
我在阅读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'
【讨论】: