简短版本:
我想使用 NGINX 作为反向代理,以便访问面向公众的 URL 的客户端从代理后面的内部 Gunicorn 服务器获取 API 数据:
external path (proxy) => internal app
<static IP>/ABC/data => 127.0.0.1:8001/data
我的位置映射不正确。
长版:
我是第一次设置 NGINX,并尝试将其用作 Gunicorn 提供的 REST API 的反向代理。该 API 在
127.0.0.1:8001
提供,我可以从服务器访问它并获得适当的响应,因此我相信该部分工作正常。它使用 Supervisord 持续运行。
我想从外部访问位于
<static IP>/ABC/data
的 API 端点之一。在 Gunicorn 服务器上,此端点位于 localhost:8001/data
。最终,我想通过 NGINX 为其他 Web 应用程序提供服务,其根如 <static IP>/foo
、<static IP>/bar
等。这些 Web 应用程序中的每一个都来自一个独立的 Python 应用程序。但目前,当我尝试从外部访问端点时,收到 444 错误代码,因此我认为我没有正确配置 NGINX。
我从 Guincorn 网站上发布的 config 中整理了我第一次尝试的 NGINX 配置。我没有将其分为单个配置,而是将其分为全局配置和特定于站点的配置。我的全局配置在 etc/nginx/nginx.conf
看起来像:
user ops;
worker_processes 1;
pid /run/nginx.pid;
error_log /tmp/nginx.error.log;
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # set to 'on' if nginx worker_processes > 1
use epoll;
# 'use epoll;' to enable for Linux 2.6+
# 'use kqueue;' to enable for FreeBSD, OSX
}
http {
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
access_log /tmp/nginx.access.log combined;
sendfile on;
server_tokens off;
server {
# if no Host match, close the connection to prevent host spoofing
listen 80 default_server;
return 444;
}
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
然后我的站点特定配置位于
/etc/nginx/sites-available
(并在
/etc/nginx/sites-enabled
中符号链接)是:
upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
# for UNIX domain socket setups
# server unix:/tmp/gunicorn_abc_api.sock fail_timeout=0;
# for a TCP configuration
server 127.0.0.1:8001 fail_timeout=0;
}
server {
# use 'listen 80 deferred;' for Linux
# use 'listen 80 accept_filter=httpready;' for FreeBSD
listen 80 deferred;
client_max_body_size 4G;
# set the correct host(s) for your site
server_name _;
keepalive_timeout 100;
# path for static files
#root /path/to/app/current/public;
location /ABC {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS
# proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://app_server;
}
# error_page 500 502 503 504 /500.html;
# location = /500.html {
# root /path/to/app/current/public;
# }
}
配置通过了
service nginx checkconfig
,但我最终在访问日志中看到以下内容:
XXX.XXX.X.XXX - - [09/Sep/2016:01:03:18 +0000] "GET /ABC/data HTTP/1.1" 444 0 "-" "python-requests/2.10.0"
我认为我没有正确配置路由。任何建议将不胜感激。
更新:
我现在可以使用它,只需进行一些更改。我注释掉了以下块:
server {
# if no Host match, close the connection to prevent host spoofing
listen 80 default_server;
return 444;
}
除非有有效的路由,否则我无法弄清楚如何获得返回 444 的行为。我很愿意,但我仍然停留在这一部分。该块似乎会吃掉所有传入的请求。我还将应用程序配置更改为:
upstream app_server {
server 127.0.0.1:8001 fail_timeout=0;
}
server {
# use 'listen 80 deferred;' for Linux
# use 'listen 80 accept_filter=httpready;' for FreeBSD
listen 80 deferred;
client_max_body_size 100M;
# set the correct host(s) for your site
server_name $hostname;
keepalive_timeout 100;
location /ABC {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS
# proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
rewrite ^/ABC/(.*) /$1 break;
proxy_pass http://app_server;
}
}
基本上,我似乎必须明确设置
server_name
并使用
rewrite
来获取到应用程序服务器的正确映射。
server {
listen 80;
server_name "";
return 444;
}
if ( $http_host !~* ^(facebook\.com|www\.facebook\.com)$ ) {
return 444;
}
location / { return 444; }