docker nginx代理nginx connect()失败(111:连接被拒绝),同时连接到上游

时间:2018-06-24 11:55:02

标签: docker nginx proxypass

我正在尝试将nginx容器作为我所有网站和Web服务的主要入口点。我设法将portainer作为容器运行,并且可以从互联网上访问它。现在,我正在尝试访问由另一个Nginx容器托管的静态网站,但这样做失败-当我转到URL时,会得到

502 Bad Gateway

我尝试将上游部分添加到我的主要Nginx的配置中,但是没有任何变化(每次更改配置后,我都会在容器内重新加载我的主要Nginx服务)。

另一方面,如果可能,添加上游是我要避免的事情,因为产生多个不同的应用程序将需要为每个应用程序添加上游-这比我期望的要多得多。

这是我的主要Nginx的配置文件:

events {
    worker_connections 1024;
}
http {
    server {
        listen 80;

        location /portainer/ {
            proxy_pass http://portainer:9000/;
        }
        location /helicon/ {
            proxy_pass http://helicon:8001/;
        }
    }
}

这是我启动主Nginx容器的方式:

docker run -p 80:80 --name nginx -v /var/nginx/conf:/etc/nginx:ro --net=internal-net -d nginx

这是我的静态网站的nginx配置文件:

events {
    worker_connections 1024;
}
http {
    server {
        listen  80;

    server_name helicon;
        root /var/www/html/helicon;

        error_log /var/log/nginx/localhost.error.log;
        access_log /var/log/nginx/localhost.access.log;
    }
}

以下是docker-compose文件创建和启动该容器的方式:

version: '3.5'
services:
    helicon:
        build: .
        image: helicon
        ports:
            - "127.0.0.1:8001:80"
        container_name: helicon
        networks:
            - internal-net
networks:
    internal-net:
        external: true

我正在使用internal-net网络将所有应用保持在同一网络中,而不是--link的弃用docker run选项

我去http://my.server.ip.address/helicon时得到502。然后我用docker logs nginx检查日志,并且有信息

2018/06/24 11:15:28 [error] 848#848: *466 connect() failed (111: Connection refused) while connecting to upstream, client: Y.Y.Y.Y, server: , request: "GET /helicon/ HTTP/1.1", upstream: "http://172.18.0.2:8001/", host: "X.X.X.X"

螺旋容器的IP地址确实为172.18.0.2。

我想念什么?也许我的方法应该与使用网络完全不同?

亲切的问候,

丹尼尔

3 个答案:

答案 0 :(得分:6)

对于在这里看到此页面的任何人,我对您对 docker 网络的理解做出了一点贡献。 我想用一个示例场景来说明。 我们正在使用 docker-compose 运行多个容器,如下所示:

  1. Docker 容器客户端
  2. Docker 容器 nginx 反向代理
  3. Docker 容器服务1
  4. Docker 容器服务2 等等...

为确保设置正确,请确保以下几点:

  1. 所有容器都在同一个网络上!
  • 首先运行:“docker network ls”以查找堆栈的网络名称
  • 第二次运行:“docker network inspect [your_stack_network_name]”
  1. 请注意,您在 docker-compose 中公开的端口与 nginx 反向代理无关! 这意味着您在 docker-compose 文件中公开的任何端口都可以在您的实际主机上使用,即您的笔记本电脑或 PC 通过浏览器,但出于代理目的,您必须将 nginx 指向服务的实际端口。

演练: 假设 service1 在端口 3000 上的容器 1 内运行,您在 docker-compose 文件中映射端口 8080,如下所示:“8080:3000”,使用本地计算机上的此配置,您可以通过浏览器在端口 8080(本地主机)上访问容器:8080) 但是对于 nginx 反向代理容器,尝试代理到 service1 时,端口 8080 不相关! dockerized nginx 反向代理将使用 docker DNS 将 service1 映射到 docker 网络中的 ip,并完全独立于本地主机查看它。 对于docker网络中的nginx反向代理,service1只监听3000端口!!! 所以一定要把nginx指向正确的端口!

答案 1 :(得分:0)

已解决。我花了几个小时思考这是一个nginx配置问题。我不断修改nginx.conf,但无法修复。我收到502错误网关,错误描述为:

failed (111: Connection refused) while connecting to upstream

我看错地方了。事实证明,我index.js文件中的http服务器正在侦听url“ localhost”。

httpServer.listen(PORT, 'localhost', async err => {

这在您的开发机器上可以正常工作,但是在容器内运行时,必须将其命名为容器本身的url。我的容器已联网,在我的情况下,该容器名为“后端”

我将网址从“ localhost”更改为“后端”,并且一切正常。

httpServer.listen(PORT, 'backend', async err => {

答案 2 :(得分:0)

我遇到了同样的错误。在 docker-compose.yml 中,我的服务端口被映射到不同的端口(例如 1234:8080),并且我在 nginx.conf 中使用了映射的端口号 (1234)。

然而,在 docker 网络内部,容器不使用它们映射的端口号。为了解决这个问题,我把proxy_pass语句改成使用正确的端口号(8080)。

为了明确工作配置是这样的:(检查nginx.conf中使用的端口号!)

docker-compose.yml

version: '3.8'

services:

...

  web1:
    ports:
      - 1234:8080
    networks:
      - net1
    
...

  proxy:
    image: nginx:latest
    networks:
      - net1

...

  networks:
    net1:
      driver: bridge

nginx.conf

... 

location /api
    ...
    proxy_pass http://web1:8080/;

我必须感谢 user8458126 为我指明了正确的方向。