docker nginx reverse proxy没有错误但返回空的有效负载

时间:2017-11-29 16:03:34

标签: docker nginx reverse-proxy

我没有运气在我的java / tomcat应用程序前放置一个简单的nginx反向代理,这在端口8080上工作正常。我的浏览器返回一个空响应,我看到服务器上没有记录或错误。

这是我的nginx Dockerfile:

FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 10040
CMD ["nginx"]

和来自nginx -T

的我的nginx.conf
$ docker run -p 10040:8080 --name rproxy --rm we1p2xxxxxxx.xxx.xx.com:11095/myapp-rproxy nginx -T
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
daemon off;
error_log /dev/stdout info;
worker_processes 1;

events { worker_connections 1024; }

http {
    access_log /dev/stdout;
    sendfile on;

    upstream docker-myapp {
        server localhost:8080;
    }

    server {
        listen 10040;

        location / {
            proxy_pass         http://docker-myapp;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }

}

当我从浏览器中调用http://localhost:10040/时,我什么都没回来 - 一个空的回复。甚至没有响应状态。

也没有记录任何内容 - 没有错误,没有访问日志,我已将其重定向到/ dev / stdout

这是nginx的启动日志记录输出:

$ docker run -p 10040:8080 --name rproxy --rm we1pxxxxxxxx.xxx.xxx.com:11095/myapp-rproxy nginx-debug
2017/11/29 14:17:06 [notice] 1#1: using the "epoll" event method
2017/11/29 14:17:06 [notice] 1#1: nginx/1.13.7
2017/11/29 14:17:06 [notice] 1#1: built by gcc 6.3.0 20170516 (Debian 6.3.0-18)
2017/11/29 14:17:06 [notice] 1#1: OS: Linux 4.9.49-moby
2017/11/29 14:17:06 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2017/11/29 14:17:06 [notice] 1#1: start worker processes
2017/11/29 14:17:06 [notice] 1#1: start worker process 7

我仍在尝试了解如何从日志记录中获取更多信息 - 例如,它正在侦听的端口号。 Cygwin netstat没有显示任何在10040端口上收听的内容 - 尽管我在Dockerfile中有EXPOSE 10040

这是docker ps

$ docker ps
CONTAINER ID        IMAGE                                          COMMAND                  CREATED             STATUS              PORTS                                        NAMES
03d17ec349f7        we1pxxxxxxxx.xxx.xxx.com:11095/myapp-rproxy    "nginx"                  52 seconds ago      Up 51 seconds       80/tcp, 10040/tcp, 0.0.0.0:10040->8080/tcp   rproxy
eaf3ed033908        we1pxxxxxxxx.xxx.xxx.com:11095/myapp           "/bin/sh -c 'java ..."   2 hours ago         Up 2 hours          0.0.0.0:8080->8080/tcp                       myapp

当我使用curl时会发生这种情况:

$ curl -i http://localhost:8080
HTTP/1.1 401
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="xx.xx.xx.COM"
Content-Length: 0
Date: Wed, 29 Nov 2017 15:57:38 GMT

$ curl -i http://localhost:10040
curl: (52) Empty reply from server
$

我在Windows 10上使用docker 17.09.0-ce-win33,使用cygwin。

任何希望,世界?

[更新2017-11-30]港口问题

Alexander Altshuler在他的回答中指出了一个简单的错误 - 我已经将nginx附加到了docker容器内的10040,所以通过尝试使用命令行-p 10040:80将10040映射到80,参数阻止了我的请求 - 来自出现了几个问题:

  • 我应该在哪里看到错误?当然我的curl请求应该超时没有端口监听?

  • 为什么docker ps PORTS字段显示为80/tcp?肯定没有打开(curl连接超时)

  • 现在,docker使用-p 10040:10040运行它,我看到了:

$ docker ps
CONTAINER ID        IMAGE                                          COMMAND                  CREATED             STATUS              PORTS                              NAMES
b6379d40d0c2        we1pxxxxxxxx.xxx.xxx.com:11095/myapp           "/bin/sh -c 'java ..."   2 minutes ago       Up 2 minutes        0.0.0.0:8080->8080/tcp             myapp
d3d5feb9e63f        we1pxxxxxxxx.xxx.xxx.com:11095/myapp-rproxy    "nginx"                  20 minutes ago      Up 20 minutes       80/tcp, 0.0.0.0:10040->10040/tcp   rproxy

并且正在做curl我明白了:

$ curl http://localhost:10040



<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.13.7</center>
</body>
</html>
&#13;
&#13;
&#13;

和NGINX吐出:

2017/11/30 10:07:32 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
2017/11/30 10:07:32 [warn] 5#5: *1 upstream server temporarily disabled while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
2017/11/30 10:07:32 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
2017/11/30 10:07:32 [warn] 5#5: *1 upstream server temporarily disabled while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
172.17.0.1 - - [30/Nov/2017:10:07:32 +0000] "GET / HTTP/1.1" 502 173 "-" "curl/7.56.1"
2017/11/30 10:07:32 [info] 5#5: *1 client 172.17.0.1 closed keepalive connection

显然丹麦仍然存在腐烂现象,但现在我得到了一些记录,我确信我会把这个记录下来。

2 个答案:

答案 0 :(得分:1)

运行docker coniatner的命令应该以

开头
docker run -p 10040:10040 ...

更新

  

为什么docker ps PORTS字段显示80 / tcp?肯定没有打开(卷曲连接超时)

我只能想象一个原因 - 你确实提供了docker run -p 80 ...

为什么nginx响应502 Bad Gateway是明确的:

您将nginx配置为连接到localhost:8080,但是从容器内部后端运行在外部主机上。

这里通常的做法 - 创建用户定义的网络:

docker network create --driver bridge mynetwork
docker run --network=isolated_nw -p 10040:8080 --name rproxy ...
docker run --network=isolated_nw --name myapp ...

Nginx配置应如下所示:

daemon off;
error_log /dev/stdout info;
worker_processes 1;

events { worker_connections 1024; }

http {
    # use docker embedded DNS server to resolve myapp host name
    resolver 127.0.0.11;

    access_log /dev/stdout;
    sendfile on;

    upstream docker-myapp {
        server myapp:8080; # !!!
    }

    server {
        listen 10040;

        location / {
            proxy_pass         http://docker-myapp;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }

}

答案 1 :(得分:0)

首先发布解决方案here

使用用户定义的桥接网络:

docker network create -d bridge myapp-net

然后我启动容器,将它们附加到myapp-net

docker run -p 8080:8080 --network=myapp-net --name myapp --rm myregistry:11095/myapp

docker run -p 10040:443 --network=myapp-net --name rproxy --rm myregistry:11095/myapp-rproxy

警告:我还不明白为什么尽管阅读docker docs

,默认的泊坞桥网络仍无法运行