Nginx部署Docker化Django+React站点出现重定向次数过多错误
部署Docker化Django+React应用出现重定向循环与静态资源404问题排查
您好,我在部署Docker化的Django+React应用时遇到Redirected too many times错误,已查阅所有公开解决方案仍未解决,特来求助。目前通过HTTPS可以正常访问Django的API接口和Admin后台,但是访问React站点时就会触发上述错误,我的Nginx配置如下:
server { listen ${LISTEN_PORT_HTTP}; server_name example.com; server_tokens off; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$server_name$request_uri; } } server { listen 443 default_server ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/live/example.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/live/example.com/privkey.pem; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /static { alias /vol/static; } location /.well-known/acme-challenge/ { root /var/www/certbot; } location /api { uwsgi_pass ${APP_HOST}:${APP_PORT}; include /etc/nginx/uwsgi_params; client_max_body_size 20M; } location /admin { uwsgi_pass ${APP_HOST}:${APP_PORT}; include /etc/nginx/uwsgi_params; client_max_body_size 20M; } }
我初步判断问题出自Nginx配置,若需更多信息我可以补充,麻烦各位帮忙排查解决,谢谢。
问题更新
我后续排查发现配置中try_files $uri $uri/ /index.html;是导致重定向循环的原因,删除该行后页面可以正常加载,但React的静态资源会走Nginx中配置的Django的static路由,导致返回404错误,报错截图如下:
我的Nginx镜像Dockerfile配置如下:
FROM nginxinc/nginx-unprivileged:1-alpine COPY --from=portfolio-front_react-app /app/build /usr/share/nginx/html COPY ./default.conf.tpl /etc/nginx/default.conf.tpl COPY ./uwsgi_params /etc/nginx/uwsgi_params COPY ./run.sh /run.sh ENV LISTEN_PORT_HTTP=8000 ENV LISTEN_PORT_HTTPS=443 ENV APP_HOST=app ENV APP_PORT=9000 USER root RUN mkdir -p /vol/static && \ chmod 755 /vol/static && \ touch /etc/nginx/conf.d/default.conf && \ chown nginx:nginx /etc/nginx/conf.d/default.conf && \ chmod +x /run.sh VOLUME /vol/static # USER nginx CMD ["/run.sh"]
请问该如何配置才能正确路由React的静态资源?
问题原因分析
你遇到的两个问题根源都来自Nginx的路由匹配规则优先级和配置错误:
- 重定向循环:
try_files $uri $uri/ /index.html中的$uri/会触发Nginx默认的目录301重定向,当访问React前端路由时,会不断在带斜杠和不带斜杠的路径之间跳转,形成循环。 - 静态资源404:Nginx的路由匹配规则中,前缀匹配长度越长优先级越高,你配置的全局
location /static优先级高于location /,所有/static开头的请求都会被转发到Django的静态资源目录/vol/static,而React打包后的静态资源存放在/usr/share/nginx/html/static/下,自然无法匹配返回404。
修复方案
直接修改Nginx的443端口server块配置即可,无需修改其他业务代码:
server { listen 443 default_server ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/live/example.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/live/example.com/privkey.pem; # 修复静态资源冲突:优先匹配React静态资源 location ^~ /static/ { root /usr/share/nginx/html; # 先检查请求的文件是否是React的静态资源,存在直接返回 if (-f $request_filename) { break; } # 不存在再转发到Django的静态资源目录 alias /vol/static/; } location / { root /usr/share/nginx/html; index index.html index.htm; # 去掉$uri/解决重定向循环,同时保留React路由的 fallback 能力 try_files $uri /index.html; } location /.well-known/acme-challenge/ { root /var/www/certbot; } location /api { uwsgi_pass ${APP_HOST}:${APP_PORT}; include /etc/nginx/uwsgi_params; client_max_body_size 20M; } location /admin { uwsgi_pass ${APP_HOST}:${APP_PORT}; include /etc/nginx/uwsgi_params; client_max_body_size 20M; } }
可选优化(避免后续冲突)
如果不想用Nginx的if判断,可以直接从根源隔离前后端静态资源路径:
- 修改Django的
settings.py配置,将静态资源前缀改为专属路径:STATIC_URL = '/dj-static/',同步修改Nginx中对应的static路由为location /dj-static/ - 或者修改React打包配置,将静态资源路径改为
/react-static/,同步加对应的Nginx匹配规则
验证步骤
修改配置后重启Nginx容器,按以下顺序验证:
- 访问React站点根路径,确认无重定向循环
- 访问React的二级路由,确认可以正常加载
- 访问Django的admin后台和api接口,确认功能正常
- 检查页面静态资源加载状态,确认无404错误
内容的提问来源于stack exchange,提问作者Muteshi
相关产品推荐
相关产品推荐

