Docker化MERN栈应用Nginx部署遇405错误及URL重复问题
问题描述
开发了一个简易Todo应用,UI基于React,API用Express/Node.js,数据库用MongoDB,本地Docker化运行正常。部署到Digital Ocean云服务器时,采用生产环境构建React并通过Nginx容器托管静态文件,同时用Nginx做反向代理,将8080端口下/api开头的请求路由至后端容器,其余请求指向UI。但通过UI发送POST请求时出现405 Not Allowed错误,且请求URL出现重复:http://123.456.7.89:8080/123.456.7.89:8080/api/v1/auth/signup,后端容器无请求日志。期望请求能被正确路由至后端并返回200状态码。
相关配置
nginx.conf
server { listen 80; server_name 123.456.7.89; location /api { proxy_pass http://backend:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } }
docker-compose.yml
version: '3' services: nginx: container_name: nginx hostname: nginx image: <react_image> ports: - 8080:80 depends_on: - backend volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf networks: - frontend-backend backend: container_name: backend hostname: backend image: <backend_image> expose: - ${ORG_BACKEND_PORT} depends_on: - db environment: - PORT=${ORG_BACKEND_PORT} - MONGODB_URL=mongodb://db:27017/organizer - SECRET_KEY=${ORG_SECRET_KEY} - TOKEN_KEY=${ORG_TOKEN_KEY} networks: - frontend-backend - backend-db db: container_name: mongodb hostname: mongodb image: mongo expose: - 27017 volumes: - ./data:/data/db networks: - backend-db networks: backend-db: frontend-backend:
解决方案
1. 修复React请求URL重复问题
URL重复是因为React应用中API请求的baseURL配置错误,应使用相对路径而非绝对路径:
- 检查并修改React代码中的API请求配置,比如axios的baseURL:
// 错误写法(绝对路径导致重复) axios.defaults.baseURL = "http://123.456.7.89:8080/api/v1"; // 正确写法(相对路径,Nginx自动代理) axios.defaults.baseURL = "/api/v1"; - 重新构建React生产镜像并部署,确保静态文件使用相对路径发起请求。
2. 修正Nginx反向代理配置
当前proxy_pass缺少路径后缀,会导致请求路径拼接错误:
- 修改
location /api块的配置,在proxy_pass末尾添加/,确保路径正确传递:location /api { proxy_pass http://backend:5000/; # 末尾添加斜杠 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; } - 重启Nginx容器使配置生效:
docker-compose restart nginx
3. 验证后端服务端口匹配
确保docker-compose.yml中的ORG_BACKEND_PORT环境变量值为5000,与Nginx代理指向的backend:5000一致。若后端实际监听其他端口,需同步修改Nginx的proxy_pass地址。
4. 排查405错误的额外可能
- 检查Express后端是否正确处理OPTIONS请求,可添加CORS中间件并配置允许的方法:
const cors = require('cors'); app.use(cors({ origin: "http://123.456.7.89:8080", methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"] })); - 确认后端路由路径与请求路径匹配,比如
/api/v1/auth/signup是否存在对应的POST路由。
内容的提问来源于stack exchange,提问作者WarriorPoet
相关产品推荐
相关产品推荐

