Nginx 用作反向代理,但不会通过套接字将流量传递给 Puma
Nginx works as a reverse proxy but doesn't pass traffic to Puma via a socket
我有一个以 Nginx 为前端的 Web 应用程序作为 Web 服务器。当它配置如下时,它可以工作。点击 http://192.168.33.10:9174/ 会产生“402 需要付款”
# /etc/nginx/sites-enabled/myapp
server {
listen 9174;
server_name 127.0.0.1;
location /status {
stub_status on;
access_log off;
}
return 402;
}
有效。
然后我试图让它将流量转发到 Puma 应用服务器,但失败了。然后我设置了一堆代理如下:
# /etc/nginx/sites-enabled/myapp
upstream sqlitething {
server www.sqlite.org;
}
upstream hwacithing {
server www.hwaci.com;
}
upstream appthing {
#server unix:///home/deployer/myapp/shared/sockets/socktest.sock
server unix:/home/deployer/myapp/shared/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name 192.168.33.10;
location / {
proxy_pass http://sqlitething;
}
}
server {
listen 8080;
server_name 192.168.33.10;
location / {
proxy_pass http://hwacithing;
}
}
server {
listen 8099;
server_name 192.168.33.10;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://appthing;
}
}
server {
listen 9175;
server_name 192.168.33.10;
return 402;
}
这是我用浏览器点击 URL 时的结果:
- http://192.168.33.10:80,它代理了 www.sqlite.org(正如预期的那样)。
- http://192.168.33.10:8080,它代理了 www.hwaci.com(如预期的那样)
- http://192.168.33.10:9175,返回了 HTTP 402(需要付款)消息(符合预期)
- http://192.168.33.10:8099 tried to redirect me to https://appthing,但什么也没发生(没想到)
套接字文件存在,权限如下:
srwxrwxrwx 1 deployer deployer 0 Jun 8 19:15 /home/deployer/myapp/shared/sockets/puma.sock
-------- 6 月 8 日更新 5:57 美国东部标准时间 ------------------
我为失败的 URL 尝试了以下方法:
$ curl -isL http://192.168.33.10:8099
HTTP/1.1 301 Moved Permanently
Server: nginx/1.1.19
Date: Wed, 08 Jun 2016 21:52:54 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Location: https://appthing/
Vary: Accept-Encoding
为了成功,我尝试了以下方法 URL
$ curl -isL http://192.168.33.10:8080
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Wed, 08 Jun 2016 21:54:46 GMT
Content-Type: text/html
Content-Length: 1167
Connection: keep-alive
Vary: Host
Last-Modified: Wed, 13 Dec 2006 14:54:32 GMT
ETag: "88047-48f-4247d938f5a00"
Accept-Ranges: bytes
<html><head><title>Hwaci Homepage</title></head><body bgcolor="white">
<font size="7"><b>Hwaci</b></font><br>
...etc...
----- 6 月 9 日更新 11:24 美国东部时间上午 --------------
我在行中添加了
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_redirect off;
到连接到 Unix 套接字的端口 8099 的 server/listen 块。我得到了相同的结果。
然后我去了 http://blog.honeybadger.io/how-unicorn-talks-to-nginx-an-introduction-to-unix-sockets-in-ruby/ 并按照他们指定的方式设置了一个小套接字服务器,但套接字位于
unix:///home/deployer/myapp/shared/sockets/socktest.sock
然后我修改了 nginx.conf 以便它不会守护进程并且错误会转到标准输出。
daemon off;
error_log /dev/stdout info;
我然后 运行 nginx as
> sudo nginx -c nginx.conf
当我 运行 卷曲击中 nginx/socket 组合时,我得到了这个:
$ curl -isL http://192.168.33.10:8099
HTTP/1.1 502 Bad Gateway
Server: nginx/1.1.19
Date: Thu, 09 Jun 2016 15:13:57 GMT
Content-Type: text/html
Content-Length: 173
Connection: keep-alive
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.1.19</center>
</body>
</html>
nginx 日志如下所示:
2016/06/09 15:13:34 [notice] 9885#0: start worker process 9889
2016/06/09 15:13:49 [info] 9886#0: *1 client 192.168.33.1 closed keepalive connection
2016/06/09 15:13:57 [crit] 9886#0: *3 connect() to unix:/home/deployer/myapp/shared/sockets/socktest.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.33.1, server: 192.168.33.10, request: "GET / HTTP/1.1", upstream: "http://unix:/home/deployer/myapp/shared/sockets/socktest.sock:/", host: "192.168.33.10:8099"
2016/06/09 15:13:57 [info] 9886#0: *3 client 192.168.33.1 closed keepalive connection
----- 6 月 9 日更新结束 ------------------ - - - - - - - ---
Puma 进程是 运行
deployer@host0:/etc/nginx/sites-enabled$ ps -ef | grep puma
deployer 21319 1 0 19:15 ? 00:00:00 puma 2.16.0 (unix:///home/deployer/myapp/shared/sockets/puma.sock) [20160608191112]
deployer 21322 21319 0 19:15 ? 00:00:09 puma: cluster worker 0: 21319 [20160608191112]
deployer 21326 21319 0 19:15 ? 00:00:10 puma: cluster worker 1: 21319 [20160608191112]
我正在按照各种配置指南中的说明将上游配置到 Puma。我做错了什么?
有没有办法查看 Puma 进程是否真的在为我的网络应用程序提供服务?
有没有办法使用 curl 或 wget 并通过 Unix 套接字 (unix:/home/deployer/myapp/shared/sockets/puma.sock) 访问 Puma 进程?
在我看来,您的 puma 应用程序正在尝试将连接从 http 升级到 https。它通过发出重定向来做到这一点。为了保持便携式应用程序的地位,它使用请求中的 HOST 字段 header 来确定其名称。
在您的位置块中,您没有指定任何 proxy_set_header
指令,因此 nginx
已插入 HOST 和 CONNECTION 的默认值。 HOST 的值为 "appthing".
您可能需要设置一些您自己的 proxy_set_header
指令让应用程序知道它的真实名称,可能说服应用程序连接已经安全并且可能设置一些 proxy_redirect
指令以映射虚假重定向到可接受的值。
详情见this document。
最终,我通过
让套接字服务器工作
> chmod 777 /home/deployer/myapp/shared/sockets/socktest.sock
这说明我的 Nginx 设置很好。
但是 Puma 插座一直出现故障。
原来Puma应用服务器背后的web应用配置为:
config.force_ssl = true
意识到这一点后,我将 Nginx 配置为侦听端口 443,打开 SSL,设置一些自签名证书,然后.........成功了。
所有这一切的教训是,我对 Nginx、Puma、套接字、权限和 SSL 的了解同时都很薄弱,这就是为什么我无法弄清楚哪里出了问题。
我有一个以 Nginx 为前端的 Web 应用程序作为 Web 服务器。当它配置如下时,它可以工作。点击 http://192.168.33.10:9174/ 会产生“402 需要付款”
# /etc/nginx/sites-enabled/myapp
server {
listen 9174;
server_name 127.0.0.1;
location /status {
stub_status on;
access_log off;
}
return 402;
}
有效。
然后我试图让它将流量转发到 Puma 应用服务器,但失败了。然后我设置了一堆代理如下:
# /etc/nginx/sites-enabled/myapp
upstream sqlitething {
server www.sqlite.org;
}
upstream hwacithing {
server www.hwaci.com;
}
upstream appthing {
#server unix:///home/deployer/myapp/shared/sockets/socktest.sock
server unix:/home/deployer/myapp/shared/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name 192.168.33.10;
location / {
proxy_pass http://sqlitething;
}
}
server {
listen 8080;
server_name 192.168.33.10;
location / {
proxy_pass http://hwacithing;
}
}
server {
listen 8099;
server_name 192.168.33.10;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://appthing;
}
}
server {
listen 9175;
server_name 192.168.33.10;
return 402;
}
这是我用浏览器点击 URL 时的结果:
- http://192.168.33.10:80,它代理了 www.sqlite.org(正如预期的那样)。
- http://192.168.33.10:8080,它代理了 www.hwaci.com(如预期的那样)
- http://192.168.33.10:9175,返回了 HTTP 402(需要付款)消息(符合预期)
- http://192.168.33.10:8099 tried to redirect me to https://appthing,但什么也没发生(没想到)
套接字文件存在,权限如下:
srwxrwxrwx 1 deployer deployer 0 Jun 8 19:15 /home/deployer/myapp/shared/sockets/puma.sock
-------- 6 月 8 日更新 5:57 美国东部标准时间 ------------------
我为失败的 URL 尝试了以下方法:
$ curl -isL http://192.168.33.10:8099
HTTP/1.1 301 Moved Permanently
Server: nginx/1.1.19
Date: Wed, 08 Jun 2016 21:52:54 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Location: https://appthing/
Vary: Accept-Encoding
为了成功,我尝试了以下方法 URL
$ curl -isL http://192.168.33.10:8080
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Wed, 08 Jun 2016 21:54:46 GMT
Content-Type: text/html
Content-Length: 1167
Connection: keep-alive
Vary: Host
Last-Modified: Wed, 13 Dec 2006 14:54:32 GMT
ETag: "88047-48f-4247d938f5a00"
Accept-Ranges: bytes
<html><head><title>Hwaci Homepage</title></head><body bgcolor="white">
<font size="7"><b>Hwaci</b></font><br>
...etc...
----- 6 月 9 日更新 11:24 美国东部时间上午 --------------
我在行中添加了
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_redirect off;
到连接到 Unix 套接字的端口 8099 的 server/listen 块。我得到了相同的结果。
然后我去了 http://blog.honeybadger.io/how-unicorn-talks-to-nginx-an-introduction-to-unix-sockets-in-ruby/ 并按照他们指定的方式设置了一个小套接字服务器,但套接字位于
unix:///home/deployer/myapp/shared/sockets/socktest.sock
然后我修改了 nginx.conf 以便它不会守护进程并且错误会转到标准输出。
daemon off;
error_log /dev/stdout info;
我然后 运行 nginx as
> sudo nginx -c nginx.conf
当我 运行 卷曲击中 nginx/socket 组合时,我得到了这个:
$ curl -isL http://192.168.33.10:8099
HTTP/1.1 502 Bad Gateway
Server: nginx/1.1.19
Date: Thu, 09 Jun 2016 15:13:57 GMT
Content-Type: text/html
Content-Length: 173
Connection: keep-alive
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.1.19</center>
</body>
</html>
nginx 日志如下所示:
2016/06/09 15:13:34 [notice] 9885#0: start worker process 9889
2016/06/09 15:13:49 [info] 9886#0: *1 client 192.168.33.1 closed keepalive connection
2016/06/09 15:13:57 [crit] 9886#0: *3 connect() to unix:/home/deployer/myapp/shared/sockets/socktest.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.33.1, server: 192.168.33.10, request: "GET / HTTP/1.1", upstream: "http://unix:/home/deployer/myapp/shared/sockets/socktest.sock:/", host: "192.168.33.10:8099"
2016/06/09 15:13:57 [info] 9886#0: *3 client 192.168.33.1 closed keepalive connection
----- 6 月 9 日更新结束 ------------------ - - - - - - - ---
Puma 进程是 运行
deployer@host0:/etc/nginx/sites-enabled$ ps -ef | grep puma
deployer 21319 1 0 19:15 ? 00:00:00 puma 2.16.0 (unix:///home/deployer/myapp/shared/sockets/puma.sock) [20160608191112]
deployer 21322 21319 0 19:15 ? 00:00:09 puma: cluster worker 0: 21319 [20160608191112]
deployer 21326 21319 0 19:15 ? 00:00:10 puma: cluster worker 1: 21319 [20160608191112]
我正在按照各种配置指南中的说明将上游配置到 Puma。我做错了什么?
有没有办法查看 Puma 进程是否真的在为我的网络应用程序提供服务?
有没有办法使用 curl 或 wget 并通过 Unix 套接字 (unix:/home/deployer/myapp/shared/sockets/puma.sock) 访问 Puma 进程?
在我看来,您的 puma 应用程序正在尝试将连接从 http 升级到 https。它通过发出重定向来做到这一点。为了保持便携式应用程序的地位,它使用请求中的 HOST 字段 header 来确定其名称。
在您的位置块中,您没有指定任何 proxy_set_header
指令,因此 nginx
已插入 HOST 和 CONNECTION 的默认值。 HOST 的值为 "appthing".
您可能需要设置一些您自己的 proxy_set_header
指令让应用程序知道它的真实名称,可能说服应用程序连接已经安全并且可能设置一些 proxy_redirect
指令以映射虚假重定向到可接受的值。
详情见this document。
最终,我通过
让套接字服务器工作> chmod 777 /home/deployer/myapp/shared/sockets/socktest.sock
这说明我的 Nginx 设置很好。
但是 Puma 插座一直出现故障。
原来Puma应用服务器背后的web应用配置为:
config.force_ssl = true
意识到这一点后,我将 Nginx 配置为侦听端口 443,打开 SSL,设置一些自签名证书,然后.........成功了。
所有这一切的教训是,我对 Nginx、Puma、套接字、权限和 SSL 的了解同时都很薄弱,这就是为什么我无法弄清楚哪里出了问题。