[英]Docker - Can't share data between containers within a volume (docker-compose 3)
我现在有一些用于 Web 应用程序的容器(nginx、gunicorn、postgres 和节点,用于从源代码和 React 服务器端渲染构建静态文件)。 在节点容器的 Dockerfile 中,我有两个步骤:构建和运行( Dockerfile.node )。 它最终在容器内有两个目录: bundle_client
- 是 nginx 和bundle_server
的静态bundle_server
- 它在节点容器本身中用于启动快速服务器。
然后我需要与 nginx 容器共享一个内置的静态文件夹( bundle_client
)。 为此,根据我docker-compose.yml
-compose 参考,我有以下服务(请参阅完整的 docker-compose.yml ):
node:
volumes:
- vnode:/usr/src
nginx:
volumes:
- vnode:/var/www/tg/static
depends_on:
- node
和卷:
volumes:
vnode:
运行docker-compose build
完成,没有错误。 运行docker-compose up
运行一切正常,我可以打开localhost:80
并且有 nginx、gunicorn 和 node express SSR 都运行良好,我可以看到一个网页,但所有静态文件都返回 404 not found 错误。
如果我使用docker volume ls
检查卷,我可以看到两个新创建的卷,名为tg_vnode
(我们在这里考虑)和tg_vdata
(请参阅完整的 docker-compose.yml)
如果我使用docker run -ti -v /tmp:/tmp tg_node /bin/bash
进入 nginx 容器,我将看不到我的www/tg/static
文件夹,该文件夹应该从节点卷映射我的静态文件。 此外,我尝试使用 nginx 容器Dockerfile.nginx
创建一个空的/var/www/tg/static
文件夹,但它保持为空。
如果我在nginx.volumes
部分的nginx.volumes
docker-compose.yml
中将bundle_client
文件夹从主机映射为- ./client/bundle_client:/var/www/tg/static
它工作正常,我可以看到所有静态文件在浏览器中与 nginx 一起提供。
我做错了什么以及如何让我的容器与 nginx 容器共享构建的静态内容?
PS:我阅读了所有文档、所有 github 问题和 stackoverflow 问答,据我所知,它必须可以工作,但没有信息可以在不工作时做什么。
UPD: docker volume inspect vnode
结果:
[
{
"CreatedAt": "2018-05-18T12:24:38Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "tg",
"com.docker.compose.version": "1.21.1",
"com.docker.compose.volume": "vnode"
},
"Mountpoint": "/var/lib/docker/volumes/tg_vnode/_data",
"Name": "tg_vnode",
"Options": null,
"Scope": "local"
}
]
文件: Dockerfile.node , docker-compose.yml
Nginx dockerfile:Dockerfile.nginx
UPD:我创建了一个简化的 repo 来重现一个问题: repo ( npm install
上有一些警告,不管它安装和构建是否正常)。 最终,当我们打开localhost:80
时,我们会在 Chrome 开发工具中看到一个空页面和静态文件( vendor.js
和app.js
)的 404 消息,但应该有一条消息React app: static loaded
由 react 脚本生成的React app: static loaded
。
你需要两个改变。 在您的节点服务中添加如下卷:
volumes:
- vnode:/usr/src/bundle_client
因为你想共享/usr/src/bundle_client
你不应该使用/usr/src/
因为这也将共享完整的文件夹和结构。
然后在您的 nginx 服务中添加如下卷:
volumes:
- type: volume
source: vnode
target: /var/www/test/static
volume:
nocopy: true
nocopy: true
明确了我们的意图,即在容器的初始映射上,不应复制映射文件夹的内容。 默认情况下,第一个映射到卷的容器将获取映射文件夹的内容。 在您的情况下,您希望这是node
容器。
同样在测试之前,请确保您运行以下命令来终止缓存的卷:
docker-compose down -v
您可以在我的测试期间看到容器中包含以下文件:
Dockerfile.node
...
COPY ./client /usr/src
...
docker-compose.yml
services:
...
node:
...
volumes:
- ./server/nginx.conf:/etc/nginx/nginx.conf:ro
- vnode:/usr/src
...
volumes:
vnode:
docker-compose up
使用这个 Dockerfile.node 和 docker-compose 部分创建一个命名卷,数据保存在 /usr/src 中。Dockerfile.nginx
FROM nginx:latest
COPY ./server/nginx.conf /etc/nginx/nginx.conf
RUN mkdir -p /var/www/tg/static
EXPOSE 80
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
docker-compose
创建的 nginx 容器将有一个空的/var/www/tg/static/
docker-compose.yml
...
nginx:
build:
context: .
dockerfile: ./Dockerfile.nginx
container_name: tg_nginx
restart: always
volumes:
- ./server/nginx.conf:/etc/nginx/nginx.conf:ro
- vnode:/var/www/tg/static
ports:
- "80:80"
- "443:443"
depends_on:
- node
- gunicorn
networks:
- nw_web_tg
volumes:
vdata:
vnode:
docker-compose up
将创建名为 volume 的vnode
并填充来自/var/www/tg/static
(现在为空)到现有 vnode 的数据。 所以,在这一点上, - nginx 容器有 /var/www/tg/static 空,因为它被创建为空(见 Dockerfile.nginx 中的 mkdir) - 节点容器有 /usr/src 目录和客户端文件(见复制Dockerfile.node) - vnode 具有来自node
的 /usr/src 和来自 nginx 的/var/www/tg/static
。
明确地说,要将数据从
node
容器中的 /usr/src 传递到nginx
容器中的/var/www/tg/static
,您需要做一些不太漂亮的事情,因为 Docker 还没有开发另一种方式:您需要结合源文件夹中的命名卷,目标中的绑定卷:nginx: build: context: . dockerfile: ./Dockerfile.nginx container_name: tg_nginx restart: always volumes: - ./server/nginx.conf:/etc/nginx/nginx.conf:ro - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static ports: - "80:80" - "443:443" depends_on: - node - gunicorn networks: - nw_web_tg
只需在 docker-compose - vnode:/var/www/tg/static
更改- /var/lib/docker/volumes/vnode/_data:/var/www/tg/static
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.