Nginx单域名部署双应用时出现无限重定向循环问题
修复Nginx中/admin路径的无限重定向问题
无限重定向的核心原因有两个:一是proxy_pass的路径拼接错误导致后端收到重复的路径前缀,二是后端应用未识别原请求的HTTPS协议,触发不必要的协议重定向。以下是针对性的修复方案:
1. 修正proxy_pass的路径匹配逻辑
根据你的admin应用(web:8000)的实际路由情况,选择对应的配置:
情况A:admin应用运行在web:8000的根路径(无需/admin前缀)
如果直接访问web:8000就能进入admin界面,修改location /admin/块:
location /admin/ { proxy_pass http://admin/; # 末尾加/,将/admin/后的路径转发到admin应用的根路径 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; # 告诉后端原请求是HTTPS proxy_redirect off; }
比如用户访问https://domain_name/admin/dashboard,Nginx会转发到http://web:8000/dashboard,避免路径重复导致的后端路由错误。
情况B:admin应用本身需要/admin前缀(需访问web:8000/admin)
如果admin应用的路由前缀就是/admin,修改location /admin/块:
location /admin/ { proxy_pass http://admin; # 不要额外加/admin,Nginx会自动拼接路径 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; }
此时用户访问https://domain_name/admin/dashboard,Nginx会转发到http://web:8000/admin/dashboard,匹配后端的路由规则。
2. 处理不带斜杠的/admin请求
为了避免用户访问https://domain_name/admin(不带斜杠)时出现路径不匹配,添加一个单独的location块:
location = /admin { return 301 /admin/; }
3. 完整的修复后配置
upstream front { server frontend:3000; } upstream admin { server web:8000; } server { listen 80; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name domain_name; ssl_certificate /etc/nginx/certs/domain_name.crt; ssl_certificate_key /etc/nginx/certs/domain_name.key; location / { proxy_pass http://front; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; } # 处理不带斜杠的/admin请求 location = /admin { return 301 /admin/; } # 根据你的admin应用路由选择上面的A或B配置 location /admin/ { proxy_pass http://admin/; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; } location /static/ { alias /home/app/web/staticfiles/; } location /media/ { alias /home/app/web/mediafiles/; } }
关键说明
- 必须添加
X-Forwarded-Proto $scheme:很多后端应用(如Django、Flask)会检测请求协议,如果发现是HTTP会强制重定向到HTTPS。如果Nginx不传递这个头,后端会认为请求是HTTP,从而重定向到HTTPS的domain_name/admin/,触发循环。 - proxy_pass末尾的
/决定路径拼接规则:如果location是/admin/,proxy_pass末尾加/,Nginx会把/admin/后面的部分直接拼到目标地址后;不加/则会把整个/admin/xxx拼到目标地址后。
内容的提问来源于stack exchange,提问作者Sara
相关产品推荐
相关产品推荐

