我现在有一些用于Web应用程序的容器(nginx,gunicorn,postgres和节点用于从源构建静态文件和React服务器端呈现)。在节点容器的Dockerfile中,我有两个步骤:构建和运行(Dockerfile.node)。它最终在容器内有两个目录:bundle_client
- 是nginx和bundle_server
的静态 - 它在节点容器本身中用于启动快速服务器。
然后我需要与nginx容器共享一个构建的静态文件夹(bundle_client
)。要根据我docker-compose.yml
中的docker-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和节点表达SSR都运行良好,我可以看到一个网页,但所有静态文件都返回404找不到错误。
如果我用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容器/var/www/tg/static
创建一个空的Dockerfile.nginx
文件夹,但它仍然是空的。
如果我将bundle_client
部分中的docker-compose.yml
nginx.volumes
部分中的- ./client/bundle_client:/var/www/tg/static
文件夹映射为docker volume inspect vnode
,它可以正常工作,我可以看到所有提供的静态文件在浏览器中使用nginx。
我做错了什么以及如何让我的容器与nginx容器共享构建的静态内容?
PS:我阅读了所有文档,所有github问题和stackoverflow Q& As,据我所知它必须工作,没有信息什么时候不做。
UPD: [
{
"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"
}
]
的结果:
npm install
文件: Dockerfile.node, docker-compose.yml
Nginx dockerfile:Dockerfile.nginx
UPD:我创建了一个简化的repo来重现一个问题:repo
(localhost:80
上有一些警告,没关系,安装和构建正常。最后,当我们打开vendor.js
时,我们会在Chrome开发工具中看到一个空白页面和404条消息,其中包含静态文件(app.js
和React app: static loaded
),但应该会生成一条消息$(document).on('click', 'table td', function() {
$(this)
.popup({
popup: $('.custom.popup')
});
});
反应脚本。
答案 0 :(得分:8)
您需要进行两项更改。在您的节点服务和广告中,如
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
您可以在我的测试中看到容器有文件
答案 1 :(得分:1)
Dockerfile.node
...
COPY ./client /usr/src
...
搬运工-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/
搬运工-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
将生成vnode
命名卷,并使用/var/www/tg/static
(现在为空)到现有vnode的数据填充。所以,在这一点上,
- nginx容器有/ var / www / tg / static为空,因为它是空的(请参阅Dockerfile.nginx中的mkdir)
- 节点容器有/ usr / src dir和客户端文件(参见在Dockerfile.node中复制的)
- vnode的内容为来自node
的/ usr / src和来自nginx的/var/www/tg/static
。
明确地说,要将/ usr / src中的数据从
node
容器传递到/var/www/tg/static
容器中的nginx
,您需要做一些不太漂亮的事情,因为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
只需按- vnode:/var/www/tg/static
- /var/lib/docker/volumes/vnode/_data:/var/www/tg/static