[英]Docker - Can't share data between containers within a volume (docker-compose 3)
I have some containers for a web app for now (nginx, gunicorn, postgres and node to build static files from source and a React server side rendering).我现在有一些用于 Web 应用程序的容器(nginx、gunicorn、postgres 和节点,用于从源代码和 React 服务器端渲染构建静态文件)。 In a Dockerfile for the node container I have two steps: build and run ( Dockerfile.node ).在节点容器的 Dockerfile 中,我有两个步骤:构建和运行( Dockerfile.node )。 It ends up with two directories inside a container: bundle_client
- is a static for an nginx and bundle_server
- it used in the node container itself to start an express server.它最终在容器内有两个目录: bundle_client
- 是 nginx 和bundle_server
的静态bundle_server
- 它在节点容器本身中用于启动快速服务器。
Then I need to share a built static folder ( bundle_client
) with the nginx container.然后我需要与 nginx 容器共享一个内置的静态文件夹( bundle_client
)。 To do so according to docker-compose reference in my docker-compose.yml
I have the following services (See full docker-compose.yml ):为此,根据我docker-compose.yml
-compose 参考,我有以下服务(请参阅完整的 docker-compose.yml ):
node:
volumes:
- vnode:/usr/src
nginx:
volumes:
- vnode:/var/www/tg/static
depends_on:
- node
and volumes:和卷:
volumes:
vnode:
Running docker-compose build
completes with no errors.运行docker-compose build
完成,没有错误。 Running docker-compose up
runs everyting ok and I can open localhost:80
and there is nginx, gunicorn and node express SSR all working great and I can see a web page but all static files return 404 not found error.运行docker-compose up
运行一切正常,我可以打开localhost:80
并且有 nginx、gunicorn 和 node express SSR 都运行良好,我可以看到一个网页,但所有静态文件都返回 404 not found 错误。
If I check volumes with docker volume ls
I can see two newly created volumes named tg_vnode
(that we consider here) and tg_vdata
(see full docker-compose.yml)如果我使用docker volume ls
检查卷,我可以看到两个新创建的卷,名为tg_vnode
(我们在这里考虑)和tg_vdata
(请参阅完整的 docker-compose.yml)
If I go into an nginx container with docker run -ti -v /tmp:/tmp tg_node /bin/bash
I can't see my www/tg/static
folder which should map my static files from the node volume.如果我使用docker run -ti -v /tmp:/tmp tg_node /bin/bash
进入 nginx 容器,我将看不到我的www/tg/static
文件夹,该文件夹应该从节点卷映射我的静态文件。 Also I tried to create an empty /var/www/tg/static
folder with nginx container Dockerfile.nginx
but it stays empty.此外,我尝试使用 nginx 容器Dockerfile.nginx
创建一个空的/var/www/tg/static
文件夹,但它保持为空。
If I map a bundle_client
folder from the host machine in the docker-compose.yml
in a nginx.volumes
section as - ./client/bundle_client:/var/www/tg/static
it works ok and I can see all the static files served with nginx in the browser.如果我在nginx.volumes
部分的nginx.volumes
docker-compose.yml
中将bundle_client
文件夹从主机映射为- ./client/bundle_client:/var/www/tg/static
它工作正常,我可以看到所有静态文件在浏览器中与 nginx 一起提供。
What I'm doing wrong and how to make my container to share built static content with the nginx container?我做错了什么以及如何让我的容器与 nginx 容器共享构建的静态内容?
PS: I read all the docs, all the github issues and stackoverflow Q&As and as I understood it has to work and there is no info what to do when is does not. PS:我阅读了所有文档、所有 github 问题和 stackoverflow 问答,据我所知,它必须可以工作,但没有信息可以在不工作时做什么。
UPD: Result of docker volume inspect vnode
: 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"
}
]
Files: Dockerfile.node , docker-compose.yml文件: Dockerfile.node , docker-compose.yml
Nginx dockerfile:Dockerfile.nginx Nginx dockerfile:Dockerfile.nginx
UPD: I have created a simplified repo to reproduce a question: repo (there are some warnings on npm install
nevermind it installs and builds ok). UPD:我创建了一个简化的 repo 来重现一个问题: repo ( npm install
上有一些警告,不管它安装和构建是否正常)。 Eventually when we open localhost:80
we see an empty page and 404 messages for static files ( vendor.js
and app.js
) in Chrome dev tools but there should be a message React app: static loaded
generated by react script.最终,当我们打开localhost:80
时,我们会在 Chrome 开发工具中看到一个空页面和静态文件( vendor.js
和app.js
)的 404 消息,但应该有一条消息React app: static loaded
由 react 脚本生成的React app: static loaded
。
Two changes you need.你需要两个改变。 In your node service add the volume like:在您的节点服务中添加如下卷:
volumes:
- vnode:/usr/src/bundle_client
Since you want to share /usr/src/bundle_client
you should NOT be using /usr/src/
because that will share the full folder and the structure too.因为你想共享/usr/src/bundle_client
你不应该使用/usr/src/
因为这也将共享完整的文件夹和结构。
And then in your nginx service add the volume like:然后在您的 nginx 服务中添加如下卷:
volumes:
- type: volume
source: vnode
target: /var/www/test/static
volume:
nocopy: true
The nocopy: true
keeps our intention clear that on initial map of the container the content of the mapped folder should not be copied. nocopy: true
明确了我们的意图,即在容器的初始映射上,不应复制映射文件夹的内容。 And by default the first container to get mapped to the volume will get the contents of the mapped folder.默认情况下,第一个映射到卷的容器将获取映射文件夹的内容。 In your case you want this to be the node
container.在您的情况下,您希望这是node
容器。
Also before testing make sure you run below command to kill the cached volumes:同样在测试之前,请确保您运行以下命令来终止缓存的卷:
docker-compose down -v
You can see during my test the container had the files:您可以在我的测试期间看到容器中包含以下文件:
Dockerfile.node Dockerfile.node
...
COPY ./client /usr/src
...
docker-compose.yml docker-compose.yml
services:
...
node:
...
volumes:
- ./server/nginx.conf:/etc/nginx/nginx.conf:ro
- vnode:/usr/src
...
volumes:
vnode:
docker-compose up
creates with this Dockerfile.node and docker-compose section a named volume with data saved in /usr/src. docker docker-compose up
使用这个 Dockerfile.node 和 docker-compose 部分创建一个命名卷,数据保存在 /usr/src 中。Dockerfile.nginx 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
will have an empty /var/www/tg/static/
这会产生使用docker-compose
创建的 nginx 容器将有一个空的/var/www/tg/static/
docker-compose.yml 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
will produce that vnode
named volume is created and filled with data from /var/www/tg/static
(empty by now) to existing vnode. docker-compose up
将创建名为 volume 的vnode
并填充来自/var/www/tg/static
(现在为空)到现有 vnode 的数据。 So, at this point, - nginx container has /var/www/tg/static empty because it was created empty (see mkdir in Dockerfile.nginx) - node container has /usr/src dir with client file (see that was copied in Dockerfile.node) - vnode has content of /usr/src from node
and /var/www/tg/static
from nginx.所以,在这一点上, - nginx 容器有 /var/www/tg/static 空,因为它被创建为空(见 Dockerfile.nginx 中的 mkdir) - 节点容器有 /usr/src 目录和客户端文件(见复制Dockerfile.node) - vnode 具有来自node
的 /usr/src 和来自 nginx 的/var/www/tg/static
。
Definitively, to pass data from /usr/src from your
node
container to/var/www/tg/static
innginx
container you need to do something that is not very pretty because Docker hasn't developed another way yet: You need to combine named volume in source folder with bind volume in destination:明确地说,要将数据从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
Just change in docker-compose - vnode:/var/www/tg/static
by - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static
只需在 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.