我正在尝试nginx反向代理多个容器。
我有2个容器,其中节点添加一个侦听8085和其他8086 我希望他们通过
访问node.app1.com
node.app2.com
所以我使用了jwilder / nginx-proxy:latest,它将位于这两个容器的fount中,并将充当反向代理。所以这是我的compose.yml文件。
version: "3"
services:
node-proxy:
build: ./node-proxy
container_name : node-proxy
restart : always
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
ports:
- 80:80
- 443:443
node-app1:
build: ./app1
container_name : node-app1
restart: always
environment:
VIRTUAL_HOST: node.app1.com
depends_on:
- node-proxy
node-app2:
build: ./app2
container_name : node-app2
restart: always
environment:
VIRTUAL_HOST: node.app2.com
depends_on:
- node-proxy
FROM jwilder/nginx-proxy:latest
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World 1\n');
}).listen(8085);
FROM node:6.11
WORKDIR /app2
COPY app1.js .
CMD node app1.js
Expose 8085
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World 2\n');
}).listen(8086);
FROM node:6.11
WORKDIR /app2
COPY app2.js .
CMD node app2.js
Expose 8086
所以当我做的时候
docker-compose up
我的所有容器都已启动并正在运行
但是什么时候做node.app1.com - >它说是未知主持人。
所以要检查是否有来自代理的请求我尝试从浏览器调用http://localhost并且它说503
我还通过
检查了侧容器中的nginx.configdocker exec -it node-proxy_id bash
cat /etc/nginx/conf.d /
它在那里,但我认为当我做node.app1.com请求不来代理。 我没有得到我错过的地方,有人可以帮我解决这个问题。
感谢您的时间
答案 0 :(得分:3)
查看app / Dockerfile的端口:
<强> ./ APP1 / app1.js 强>
})听(8085)。
和
<强> ./ APP1 / Dockerfile 强>
他们很不匹配。曝光8086
我缺少的部分是jwilder/nginx-proxy
反映泊坞者寻找需要代理的容器。
原帖:
我猜您的问题是反向代理容器无法访问每个应用。因此,从node-app1和node-app2中删除depends_on
并添加node-proxy:
links:
- node-app1
- node-app2
反向代理需要启动两个应用程序,而不是相反。也可以使用links
代替depends_on
。
来自docs:
<强> depends_on 强>
服务之间的快速依赖关系,它有两个影响:
docker-compose up将按依赖顺序启动服务。在以下示例中,db和redis将在web之前启动。
docker-compose up SERVICE将自动包含SERVICE的依赖项。在以下示例中,docker-compose up web will 还创建并启动db和redis。
<强>链接强>
链接服务的容器可以在与别名相同的主机名上访问,如果没有指定别名,则可以访问服务名称。
链接还以与depends_on相同的方式表达服务之间的依赖关系,因此它们确定了服务启动的顺序。
我也不确定如何在代理配置中获取此容器的IP地址。您可以使用(如文档中所述)别名或服务名称。 (在你的情况下是node-app1和node-app2)
答案 1 :(得分:0)
当您将links
或depends_on
设置为其他服务时,默认情况下,docker-compose会在同一个泊坞网络中将其他服务主机名设置为container_name
。
在您的情况下,我建议添加links
作为@Mathias回复。
version: "3"
services:
node-app1:
build: ./app1
container_name : node-app1
restart: always
expose:
- "8085"
environment:
VIRTUAL_HOST: node.app1.com
node-app2:
build: ./app2
container_name : node-app2
restart: always
expose:
- "8086"
environment:
VIRTUAL_HOST: node.app2.com
node-proxy:
build: ./node-proxy
container_name : node-proxy
restart : always
links:
- node-app1
- node-app2
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
ports:
- 80:80
- 443:443
<强>更新强>
我注意到Nginx配置有upstream
指令来保存多个主机名。您应该能够将node-app1
卷曲为:
$ curl -H 'Host: node.app1.com' localhost
Hello World 1
您还可以修改etc/hosts
容器中node-proxy
文件中的最后一行:
172.20.0.4 [docker-network-alias] node.app1.com node.app2.com
然后,您应该可以直接在http://node.app1.com
容器内访问node-proxy
。
这是set up nginx virtual hosts on ubuntu 16 04
的教程评论I:
根据我的理解,nginx-proxy
倾向于代理对后端服务的请求,后端服务不需要在/etc/hosts
文件中注册主机名。因此,我们使用Host
标头触发请求,该标头是Nginx upstream
块中的虚拟主机名。
在每个应用容器设置中创建环境变量nginx-proxy
时,VIRTUAL_HOST
已为您完成此部分。但这并不意味着我们可以直接访问浏览器中的node.app1.com
,并期望请求代理并由node-app1
容器进行响应。
返回请求转发部分,请求来自端口80/443的localhost
,由Nginx监听。然后Nginx检查Host
标题以进入特定位置块。这就是为什么您无法在浏览器中直接访问http://node.app1.com的原因,因为该主机名永远不会在etc/hosts
中真正注册,因此任何服务器,应用或我们的nginx-proxy
都无法解决该主机名。 。
如果我们想通过浏览器访问thay主机名,则需要etc/hosts
的额外设置。
nginx-proxy
项目提供了一些模板设置,因此您可以获取应用容器的IP及其VIRTUAL_HOST
环境,然后将其附加到/etc/hosts
文件。但通过这种方式,这将直接访问节点应用服务器,而不是来自nginx-proxy
的代理。
如果没有关注生产级别,我建议在etc/hosts
文件的nginx-proxy
文件的最后一行添加应用程序域,然后它应该按预期工作。否则,nginx-proxy
模板的主机名动态绑定工作是必要的。