当通过Docker-compose运行时,Nginx无法找到上游节点应用程序

时间:2017-12-26 16:31:24

标签: node.js docker nginx docker-compose

我有一个超级简单的Node应用程序和一个Nginx配置,它充当Node应用程序的反向代理。如果我在本地运行Nginx(通过自制程序)和Node应用程序,一切正常。如果我在端口8080访问Nginx配置定义的服务器,我会从端口3000上运行的节点应用程序获得输出。

我一直试图将这个简单的设置转换为使用Docker,并编写了以下Docker-compose文件:

version: '3.0'
services:
  web:
    build: .
    ports:
      - 3000:3000
  nginx:
    build:
      context: .
      dockerfile: Dockerfile.nginx
    ports:
      - 8080:8080

在运行docker-compose up时,会构建映像,并且控制台中没有错误消息。在访问localhost:3000时,我从Node应用程序获得响应,但在访问localhost:8080时,我收到一个Nginx 502错误页面,并在终端中出现以下错误:

  连接时

connect()失败(111:拒绝连接)   upstream,client:172.18.0.1,server:localhost,request:" GET /   HTTP / 1.1",上游:" http://127.0.0.1:3000/",主持人:" localhost:8080"

节点应用程序的我的Dockerfile如下所示:

FROM node:carbon

WORKDIR /app

ADD . /app

RUN npm install

CMD ["node", "."]

EXPOSE 3000

并且Dockerfile.nginx看起来像这样:

FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf

并且nginx.conf看起来像这样:

events {
  worker_connections  1024;
}

http {

  upstream node_app {
    server 127.0.0.1:3000;
  }

  server_tokens off;

  # Define the MIME types for files.
  include       mime.types;
  default_type  application/octet-stream;

  # Speed up file transfers by using sendfile()
  # TODO: Read up on this
  sendfile on;

  server {
    listen 8080;
    server_name localhost;

    location / {
      proxy_pass http://node_app;
      proxy_http_version 1.1;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}

在启动Docker时,我可以看到Nginx正在端口8080上运行(因为我看到502 Nginx页面),我可以看到节点应用正在运行(因为我可以在localhost:3000访问它)。我无法理解为什么我从nginx获得502。

我尝试过使用各种不同的东西,例如使用links来链接容器和depends_on,但似乎没有任何区别。我还使用docker-compose up --build来确保每次进行更改时都不会缓存以前的版本。

编辑:似乎使它工作的东西是将一个container_name属性添加到docker-compose中:

  web:
    container_name: nodeapp
    build:
      context: .
      dockerfile: Dockerfile.node
    ports:
      - 3000:3000

然后在nginx.conf中的上游node_app配置中使用该容器名称:

  upstream node_app {
    server nodeapp:3000;
  }

这对我没有意义?!

1 个答案:

答案 0 :(得分:5)

问题是在您的Nginx配置中,您将Web服务的IP引用为127.0.0.1,这是运行docker容器的主机的环回地址。这可能会取决于您的设置(操作系统,防火墙)或可能不会。

正确的方法是使nginx服务取决于docker-compose.yml文件中的web服务,并更新Nginx配置以按名称引用Web服务({{1而不是IP地址。 Here你可以找到更多与docker compose相关的信息,具体取决于能力。

更新的docker-compose.yml文件将是:

web

请注意,我已停止公开version: '3.0' services: web: build: . nginx: build: context: . dockerfile: Dockerfile.nginx ports: - 8080:8080 depends_on: - web 服务的端口。您可能需要保留它来监控Web服务,但web服务不需要它。

通过对docker-compose.yml文件的更新,Nginx配置如下:

nginx