【发布时间】:2018-10-28 22:58:05
【问题描述】:
我现在有一些用于 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 和 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 部分的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 脚本生成的消息 React app: static loaded。
【问题讨论】:
-
在多个服务中使用相同的卷容器的问题在于,首先加载的容器会将自己的数据复制到卷中,其余的都将看到相同的内容。如果你想避免这种情况,你需要使用
nocopyoption。我在您的作文中看到您在多个地方使用过它,只有一个地方会将其内容放入卷中并以初始内容获胜。如果在挂载后发生,则构建会将文件置于运行时。我很难想象你的作文,但看看这些指针是否有帮助 -
是的,“...首先加载的容器会将其自己的数据复制到卷中,其余的都将看到相同的内容”,这就是我需要的 - 最初复制内置 @ 987654356@ artefact 在一个卷中,然后在 nginx 容器中使用它。我通过将
depends_on.node设置为nginx容器来确保节点容器排在第一位。也许我搞砸了 Dokerfile 并编写了文件并误解了它的实际工作原理。您能否解释一下-“如果在挂载后发生,则构建会将文件置于运行时。”。我不确定我是否理解它。 -
我根据长语法将
nocopy: true添加到nginx.volumes,并在gunicorn容器中使用vnode进行注释,但不幸的是nginx容器内的文件夹仍然是空的。 -
有没有可能得到一个 repo 来调试?
-
你能添加你的 Dockerfile.nginx 文件吗?我正在尝试重现您的错误。我有一些线索,但我需要检查 nginx 容器
标签: docker docker-compose docker-volume