有时我们在一台机器上部署多个 uWSGI 服务,并提供 HTTPS 支持。使用 proxy_pass 代替 uwsgi_pass 是很简单的方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
server {
listen 443;
server_name your.domain.com;
root /srv/www/static;
index index.html index.htm;
ssl on;
ssl_certificate /your/ssl/certificate.pem;
ssl_certificate_key /your/ssl/certificate.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ =404;
}
# 把 test1 代理到 5000 端口
location ^~/test1/ {
proxy_pass http://localhost:5000;
}
# 仅允许 1.2.3.4 访问
location ^~/test1/private/ {
allow 1.2.3.4;
deny all;
proxy_pass http://localhost:5000;
}
# 把 test2 代理到 5001 端口
location ^~/test2/ {
proxy_pass http://localhost:5001;
}
}

如果在服务器前端启用了负载均衡,需要做一些调整。因为负载均衡服务器已经帮我们把 https 流量进行解密了,到了 web 服务器就不必再配置证书。因此 nginx 改为 listen 80 端口。

这么做的问题是,当 uwsgi app(这里是 flask) 的内部路由进行跳转的时候 (flask url_for),由于侦听的是 80 端口,app 会自动把原有的 https url 路由到 http url。导致跳转失败。

例如:

当我们在 https://your.domain.com/test1/ 中跳转 url_for('index') 的时候,URL 会变成 http://your.domain.com/index/ ,这会导致访问失败。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name your.domain.com;
root /srv/www/static;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ^~/test1/ {
proxy_pass http://localhost:5000;
}
}

解决方案,就是把 proxy_pass 改回 uwsgi_pass ,并修改 uwsgi_params,在最后加入:

1
uwsgi_param UWSGI_SCHEME https;

修改后的 nginx 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 80;
server_name your.domain.com;
root /srv/www/static;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ^~/test1/ {
uwsgi_pass 127.0.0.1:5000;
include uwsgi_params;
}
}

更多内容请阅读: 部署Flask + uWSGI + Nginx

(全文完)

留言

2017-04-12
次访问