FastAPI配置--root-path /api时React+Nginx部署404问题
React 应用必须请求localhost:3000/api/路径,不要直接请求8000端口的后端服务。该架构下Nginx是唯一对外暴露的入口,直接请求8000端口会触发跨域、路径匹配错误,也不符合前后端同域部署的设计目标。
当前404错误是三个配置问题叠加导致:
- React端请求配置未生效,错误的baseURL或硬编码地址导致请求直接发往8000端口,没有走Nginx代理路径
- Nginx反向代理的路径转发规则和FastAPI的
--root-path参数逻辑不匹配,路径前缀转发错误 - React构建后的静态资源未配置路由回退,前端路由刷新会触发404
1. 修正React端请求配置
移除所有硬编码的带域名、端口的全路径请求,统一使用相对路径:
- 若使用axios,在项目入口文件(如
src/index.js)添加全局配置:
import axios from 'axios' axios.defaults.baseURL = '/api'
后续接口请求直接写路径后缀即可,例如请求fleets接口写axios.get('/fleets/'),最终会自动拼接为/api/fleets/,和当前页面同域同端口,自动走Nginx代理。
- 若使用原生fetch,直接写相对路径,例如
fetch('/api/day?day_num=3'),不要写带http://的全路径。
注意:修改完React代码必须重新执行build,否则容器内的静态资源还是旧版本,配置不会生效。之前修改baseURL无效果基本都是没有重新构建前端镜像、未生成新的build文件导致的。
2. 修正Nginx配置
当前配置中proxy_pass带尾部斜杠,会自动切掉/api/前缀再转发给后端,和FastAPI配置的--root-path /api逻辑冲突。替换nginx-setup.conf为以下内容,同时补全前端静态资源路由回退规则:
upstream api { server backend:8000; } server { listen 8080; root /var/www/react; index index.html index.htm; # 前端静态资源路由,支持React Router刷新不404 location / { try_files $uri $uri/ /index.html; } # API反向代理 location /api/ { # 注意:不要加尾部斜杠,会保留/api前缀完整转发给后端 proxy_pass http://api; proxy_set_header Host $http_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_pass http://api不带尾部斜杠时,Nginx会将包含/api/前缀的完整路径原封不动转发给FastAPI,和--root-path /api配置完全匹配,接口、自动文档、重定向逻辑都会正常工作。
3. (可选优化)调整docker-compose配置
生产环境不需要对外暴露8000端口,可以删除backend服务的ports配置,避免后端端口直接暴露,仅允许Nginx通过内部网络访问后端:
services: backend: build: context: ./backend command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --root-path /api # 注释或删除以下端口映射配置 # ports: # - 8000:8000
同域部署下CORS配置不会触发,现有CORS规则可保留用于本地开发,不影响生产环境运行。
4. 重启服务验证
修改完所有配置后,执行以下命令重新构建并启动服务,确保前端build文件为最新版本:
docker-compose down -v docker-compose up --build -d
修复完成后符合以下表现即为配置正确:
- 访问
localhost:3000正常加载React页面 - 访问
localhost:3000/api/fleets/正常返回接口数据 - 访问
localhost:3000/api/docs正常打开FastAPI自动文档 - React页面内发起的请求地址为
localhost:3000/api/xxx,返回200状态码 - 访问不带尾部斜杠的
localhost:3000/api/fleets会自动重定向到带斜杠的路径,正常返回数据
内容的提问来源于stack exchange,提问作者cpage

