nginx-proxy用于多个节点应用程序泊坞窗

时间:2017-08-16 11:24:28

标签: node.js docker proxy docker-compose

我正在尝试nginx反向代理多个容器。

我有2个容器,其中节点添加一个侦听8085和其他8086 我希望他们通过

访问
  

node.app1.com

     

node.app2.com

所以我使用了jwilder / nginx-proxy:latest,它将位于这两个容器的fount中,并将充当反向代理。所以这是我的compose.yml文件。

搬运工-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

./节点代理/ Dockerfile

FROM jwilder/nginx-proxy:latest

./ APP1 / app1.js

var http = require("http");

http.createServer(function (request, response) {

   response.writeHead(200, {'Content-Type': 'text/plain'});
   response.end('Hello World 1\n');
}).listen(8085);

./ APP1 / Dockerfile

FROM node:6.11
WORKDIR /app2
COPY app1.js .
CMD node app1.js
Expose 8085

./ APP2 / app2.js

var http = require("http");

http.createServer(function (request, response) {

   response.writeHead(200, {'Content-Type': 'text/plain'});
   response.end('Hello World 2\n');
}).listen(8086);

./ APP2 / Dockerfile

FROM node:6.11
WORKDIR /app2
COPY app2.js .
CMD node app2.js
Expose 8086

所以当我做的时候

docker-compose up 

我的所有容器都已启动并正在运行

enter image description here

但是什么时候做node.app1.com - >它说是未知主持人。

所以要检查是否有来自代理的请求我尝试从浏览器调用http://localhost并且它说503

enter image description here

我还通过

检查了侧容器中的nginx.config

enter image description here

  

docker exec -it node-proxy_id bash

     

cat /etc/nginx/conf.d /

它在那里,但我认为当我做node.app1.com请求不来代理。 我没有得到我错过的地方,有人可以帮我解决这个问题。

感谢您的时间

2 个答案:

答案 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)

当您将linksdepends_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模板的主机名动态绑定工作是必要的。