提问者:小点点

nginx docker容器:502错误的网关响应


我有一个监听8080端口的服务。这个不是容器。

然后,我使用官方镜像创建了一个nginx容器:

docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d -p 443:443 -p 80:80 nginx

毕竟:

# netstat -tupln | grep 443
tcp6       0      0 :::443                  :::*                    LISTEN      3482/docker-proxy
# netstat -tupln | grep 80
tcp6       0      0 :::80                   :::*                    LISTEN      3489/docker-proxy
tcp6       0      0 :::8080                 :::*                    LISTEN      1009/java

Nginx配置为:

upstream eighty {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name eighty.domain.com;

    location / {
      proxy_pass                        http://eighty;
    }
}

我已经检查过我可以用#curlhttp://127.0.0.1:8080连接到这个服务器

 <html><head><meta http-equiv='refresh'
 content='1;url=/login?from=%2F'/><script>window.location.replace('/login?from=%2F');</script></head><body
 style='background-color:white; color:white;'>
 ...

它似乎运行良好,但是,当我尝试使用浏览器访问时,nginx告诉bt 502错误的网关响应。

我发现这可能与非容器化进程打开的端口和容器之间的可见性有关。我可以将容器稳定连接到其他非容器进程打开的端口吗?

编辑

上游{server127.0.0.1:8080;}的日志:

2016/07/13 09:06:53 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:06:53 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"

上游{server0.0.0.0:8080;}的日志:

62.57.217.25 - - [13/Jul/2016:09:00:30 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" 2016/07/13 09:00:30 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client:
62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "eighty.domain.com" 2016/07/13 09:00:32 [error] 5#5: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:00:32 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"

有什么想法吗?


共3个答案

匿名用户

Localhost在容器方面有点棘手。在docker容器中,localhost指向容器本身。这意味着,对于这样的上游:

upstream foo{
  server 127.0.0.1:8080;
}

upstream foo{
  server 0.0.0.0:8080;
}

你告诉nginx将你的请求传递给本地主机。但是在docker-容器的上下文中,localhost(以及相应的ip地址)指向容器本身:

通过寻址127.0.0.1如果容器不在主机网络上,您将永远无法访问主机。

您可以选择在与主机相同的网络上运行nginx:

docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d --net=host nginx

请注意,在这种情况下,您不需要公开任何端口。

尽管你失去了docker网络的好处,但这种方法仍然有效。如果你有多个容器应该通过docker网络进行通信,这种方法可能会有问题。如果你只想用docker部署nginx,而不想使用任何高级docker网络功能,这种方法很好。

另一种方法是重新配置nginx上游指令,通过添加其远程IP地址直接连接到主机:

upstream foo{
  //insert your hosts ip here
  server 192.168.99.100:8080;
}

容器现在将通过网络堆栈并正确解析您的主机:

如果你有DNS名,也可以使用。确保docker知道你的DNS服务器。

匿名用户

帮我把这行代码proxy_set_headerHost$http_host;

server {
   listen            80;
   server_name  localhost;
location / {
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header Host $http_host;
   proxy_set_header X-NginX-Proxy true;

   proxy_redirect off;
   proxy_pass http://myserver;
}

匿名用户

为了完成其他答案,我使用mac进行开发,并直接在上游使用host. docker.内部为我工作,无需传递主机远程IP地址。这是代理nginx的配置:

events { worker_connections 1024; }

http {
    upstream app1 {
        server host.docker.internal:81;
    }

    upstream app1 {
        server host.docker.internal:82;
    }
    
    server {
        listen 80;
        server_name app1.com;
    
        location / {
          proxy_pass    http://app1;
        }
    }

    server {
        listen 80;
        server_name app2.com;
    
        location / {
          proxy_pass    http://app2;
        }
    }
}

如您所见,我在nginx代理后面为不同的应用程序使用了不同的端口。我将端口81用于app1,将端口82用于app2,app1和app2都有自己的nginx容器:

对于app1:

docker run --name nginx -d -p 81:80 nginx

对于app2:

docker run --name nginx -d -p 82:80 nginx

另外,请参阅此链接了解更多详细信息:docker文档for mac