[英]How volume mounting works in docker-compose
我有一个非常简单的 node js 应用程序,项目结构如下所示。
index.js
package.json
package-lock.json
Dockerfile
FROM node:12.18.2-alpine
WORKDIR /test-app
COPY package.json package-lock.json ./
RUN npm i
COPY . ./
EXPOSE 3000
ENTRYPOINT [ "node", "index.js" ]
docker-compose.yml
version: '3.2'
services:
test-app:
build: .
ports:
- "3000:3000"
volumes:
- .:/test-app
- "test_app_node_modules:/test-app/node_modules"
volumes:
test_app_node_modules:
driver: local
如果您查看docker-compose.yml
文件中的volumes
部分,首先我将主机上的当前目录挂载到容器上的test-app
目录。 这表示:
node_modules
构建期间安装在容器的test-app
目录中的 node_modules 也被覆盖。 volumes
部分的下一步被命名为卷。 这表示:
test-app/node_modules
中的所有内容复制到test_app_node_modules
卷。 但是test-app/node_modules
是空的,因为第 1 步覆盖了它。如果是这样,它应该会导致缺少依赖项错误,但我的应用程序运行正常。 我不确定我从哪里得到 node_modules。
另外,我在主机目录中看到一个空的 node_modules 文件夹。 我认为这背后的原因是"test_app_node_modules:/test-app/node_modules"
在容器中查找node_modules
,但它不存在,因此它创建了一个,结果,它被反射回主机目录。
我无法掌握卷安装的想法。 这里的流程是什么? 当没有节点模块时,如何开始将其存储到卷中?
在纯粹的机械层面上,这里发生了几件事。
Docker 对卷安装进行排序。 它知道/test-app/node_modules
是/test-app
的子目录。 所以 Docker 将
node_modules
目录这是主机上的空node_modules
目录的来源: Docker 在完成绑定挂载后将其创建为挂载点,因此那里的更改会反映在主机内容中。
当命名卷被挂载到容器中时,当且仅当命名卷为空时, Docker 会将镜像中的内容复制到卷中; 这个特定步骤忽略了容器中已经安装了一个卷。 (如果卷是匿名卷,这也适用,您在其他节点示例中可以看到;它不适用于主机绑定挂载,如果卷中有旧内容,或者在 Kubernetes 上。)
所以这就是为什么这显然有效。 作为此问题说明的其他答案,这不是 Docker 的特别有效使用。 如果您需要实时开发设置,我还建议您只删除这些volumes:
,并直接在主机上运行node index.js
。
in your docker file you have first created WORKDIR /test-app
inside it you have added a package.json
file and installed dependencies RUN npm i
so now there is already node_module
present inside docker image itself.
之后使用COPY. ./
COPY. ./
您正在向 docker 图像添加额外的文件,如index
和其他所有文件。
如果您将删除整个volume
部分,那么它也将工作,因为您的 docker 图像包含代码及其依赖项。
version: '3.2'
services:
test-app:
build: .
ports:
- "3000:3000"
我不确定您为什么要以这种方式设置 docker 容器,但它不起作用的原因是对卷和绑定安装的工作方向的误解。 你说:
它应该将容器内的 test-app/node_modules 中的所有内容复制到 test_app_node_modules 卷。 但是 test-app/node_modules 是空的,因为第 1 步覆盖了它。
这是从前到后。 使用卷时,该卷被复制到目标中。 这就是卷的全部意义——它们旨在让您即使重建容器也能保留数据。 如果您使用绑定安装卷,则主机目录将复制到 docker 容器中的目标中。 所以你在主机上的test_app_node_modules
目录被复制到容器中的/test-app/node_modules
中。 大概test_app_node_modules
包含您的所有节点模块,因此您不会收到有关缺少模块的错误。
只有在您的容器实际运行时,容器中运行的代码才能更新/删除卷中的数据 - 而不是在您构建容器时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.