单服务器多端点部署2个Django应用的Nginx配置及路由异常问题
问题根因
- 当前Nginx配置中
proxy_pass http://app1;没有加后缀斜杠,会把完整的/api/xxx路径直接传给后端Django服务。Django默认部署在根路径下,只能识别/admin路由,无法匹配/api/admin路径。 - Django生成重定向地址时不知道外层Nginx有路由前缀,返回的重定向响应头
Location直接为/admin/,同时你配置了proxy_redirect off;关闭了Nginx自动修正重定向地址的能力,最终导致请求跳转到不存在的根路径/admin。
解决方案
第一步(推荐,一劳永逸):修改Django应用配置
分别编辑两个Django服务的settings.py文件,新增如下配置:
# /api前缀对应的Django应用加这个配置,/data前缀的对应改成FORCE_SCRIPT_NAME = '/data' FORCE_SCRIPT_NAME = '/api' # 生产环境请替换为实际域名,不要留* ALLOWED_HOSTS = ['*'] # 如果有跨域或CSRF校验失败的情况,新增下面的配置,同样替换为实际域名 CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1']
配置后Django生成重定向、内部URL时会自动带上对应前缀,从根源避免路径缺失问题。
第二步:调整Nginx配置
修改后完整配置如下:
upstream app1 { server 0.0.0.0:8000; } upstream app2 { server 0.0.0.0:8090; } server { listen 80; server_name localhost; error_log /var/log/webapp/error.log debug; access_log /var/log/webapp/access.log; location / { proxy_pass http://0.0.0.0:3000; 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-Proto $scheme; } location /api { location /api/static { alias /var/tmp/app1/static; } # 末尾加/ 会把/api前缀剥离后传给后端,例如/api/admin/会转成/admin/传给8000端口 proxy_pass http://app1/; 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-Proto $scheme; # 自动修正Django返回的重定向地址,把/xxx开头的路径补全为/api/xxx proxy_redirect ^/ /api/; } location /data { location /data/static { alias /var/tmp/app2/static; } proxy_pass http://app2/; 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-Proto $scheme; proxy_redirect ^/ /data/; } }
修改完成后执行nginx -s reload重载配置,重启两个Django服务即可生效。如果暂时不方便修改Django配置,仅调整Nginx配置也可以解决当前重定向问题,但Django内部生成的其他路径(比如静态资源、页面内链接)仍可能存在前缀缺失问题。
内容的提问来源于stack exchange,提问作者A H Bensiali
相关产品推荐
相关产品推荐

