简体   繁体   English

Nginx 通过 Docker-compose 运行时找不到上游节点应用程序

[英]Nginx can't find upstream node app when running via Docker-compose

I have a super simple Node app and an Nginx config which acts as a reverse proxy to the Node app.我有一个超级简单的 Node 应用程序和一个 Nginx 配置,它充当 Node 应用程序的反向代理。 Everything works fine if I run Nginx (via homebrew) and the Node app locally.如果我在本地运行 Nginx(通过自制软件)和 Node 应用程序,一切正常。 If I visit the server defined by the Nginx config at port 8080 I get the output from the node app, which is running on port 3000.如果我在端口 8080 访问由 Nginx 配置定义的服务器,我会从运行在端口 3000 上的节点应用程序获得 output。

I've been trying to convert this simple setup to use Docker and have written the following Docker-compose file:我一直在尝试将这个简单的设置转换为使用 Docker 并编写了以下 Docker-compose 文件:

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

On running docker-compose up the images are built and there are no error messages in the console.在运行docker-compose up ,图像已构建并且控制台中没有错误消息。 On visiting localhost:3000 I get the response from the Node app but on visiting localhost:8080 I get an an Nginx 502 error page and the following error in the terminal:在访问localhost:3000时,我得到了 Node 应用程序的响应,但在访问localhost:8080时,我得到一个 Nginx 502 错误页面和终端中的以下错误:

connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: " http://127.0.0.1:3000/ ", host: "localhost:8080" connect() 连接到上游时失败(111:连接被拒绝),客户端:172.18.0.1,服务器:localhost,请求:“GET / HTTP/1.1”,上游:“ http://127.0.0.1:3000/ ”,主机:“本地主机:8080”

My Dockerfile for the node app looks like so:我的节点应用程序的 Dockerfile 如下所示:

FROM node:carbon

WORKDIR /app

ADD . /app

RUN npm install

CMD ["node", "."]

EXPOSE 3000

and the Dockerfile.nginx looks like so: Dockerfile.nginx 看起来像这样:

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

and the nginx.conf looks like so: 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;
    }
  }
}

On starting Docker up I can see that Nginx is running on port 8080 (because I see the 502 Nginx page) and I can see that the node app is running (because I can visit it at localhost:3000). On starting Docker up I can see that Nginx is running on port 8080 (because I see the 502 Nginx page) and I can see that the node app is running (because I can visit it at localhost:3000). I can't work out why I get the 502 from nginx.我不知道为什么我从 nginx 得到 502。

I've tried using various different things like using links to link the containers and depends_on but nothing seems to make any difference.我尝试过使用各种不同的东西,比如使用links来链接容器和depends_on ,但似乎没有任何区别。 I'm also using docker-compose up --build to make sure I'm not caching previous builds each time I make a change.我还使用docker-compose up --build来确保每次进行更改时都不会缓存以前的构建。

EDIT: Something that seems to make it work is to add a container_name property in to the docker-compose:编辑:似乎使它起作用的是在 docker-compose 中添加一个 container_name 属性:

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

and then using that container name in the upstream node_app config in nginx.conf:然后在 nginx.conf 的上游 node_app 配置中使用该容器名称:

  upstream node_app {
    server nodeapp:3000;
  }

which makes no sense to me?!这对我来说没有意义?!

The problem is that in your Nginx configuration you are referencing the IP of the Web service as 127.0.0.1 which is the loopback address of the Host machine running the docker container. 问题在于,在您的Nginx配置中,您将Web服务的IP引用为127.0.0.1,这是运行docker容器的主机的环回地址。 This may work depending on your setup (OS, firewall) or may not. 这可能会起作用,具体取决于您的设置(操作系统,防火墙),也可能不起作用。

The correct way would be to make the nginx service depends on the web service in your docker-compose.yml file and update the Nginx config to reference the Web service by name ( web ) instead of by IP address. 正确的方法是使nginx服务依赖于docker-compose.yml文件中的web服务,并更新Nginx配置以按名称( web )而不是IP地址引用该Web服务。 Here you can find more info related to docker compose depends on capability. 在这里您可以找到与docker compose相关的更多信息,具体取决于功能。

The updated docker-compose.yml file would be: 更新后的docker-compose.yml文件为:

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

Notice that I have stop exposing the port of the web service. 请注意,我已经停止公开web服务的端口。 May be you need to keep it to monitor the Web service but is not required for the nginx service. 可能是您需要保留它以监视Web服务,但nginx服务不是必需的。

With this update to the docker-compose.yml file the Nginx config will be as follows: 通过对docker-compose.yml文件的此更新,Nginx配置将如下所示:

events {
  worker_connections  1024;
}

http {

  upstream node_app {
    server web: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;
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 docker-compose up 找不到模块,但从 bash 运行有效 - docker-compose up can't find module, but running from bash works 无法调试节点,使用 nodemon,dockerfile 和 docker-compose - Can't debug node, with nodemon, dockerfile and docker-compose 移动 docker-compose.yml 文件时,Nginx 图像的 docker-compose 不起作用 - docker-compose of Nginx image doesn't work when the docker-compose.yml file is moved 带有 docker-compose 的 Node.js 容器无法运行 - Node.js container with docker-compose can't run 使用docker-compose run时无法调试,但是docker-compose up可以工作 - Can't debug when using `docker-compose run`, but `docker-compose up` works docker-compose找不到/运行start.sh - docker-compose can't find/run start.sh docker-compose up 未正确运行应用程序 - docker-compose up not running app correctly Docker-compose 在运行连接到 MongoDB 云集群的 nodejs 应用程序时给出:“node|SyntaxError: Unexpected token import”错误 - Docker-compose gives: “node|SyntaxError: Unexpected token import” error when running nodejs app that connects to MongoDB cloud cluster 当 docker-compose 退出时运行可执行文件 - Running an executable when the docker-compose exits 找不到在 docker compose 环境中运行的节点 js 应用程序的模块 - Cannot find module for a node js app running in a docker compose environment
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM