Docker Compose部署中Nginx反向代理后端API遇404问题排查
问题:Docker Compose部署的前端Nginx反向代理/api/v1/返回404
我通过Docker Compose部署了包含frontend、backend、db的应用架构:
- frontend容器内置Nginx,提供编译后的React应用并反向代理后端API
- frontend可正常访问,但请求/api/v1/时返回404
- 已验证frontend容器内执行
curl http://backend:8000能得到200响应 - 应用通过公司Nginx反向代理到独立VM的/myapp/路径下,调整frontend的Nginx配置为/myapp/和/myapp/api/v1/后仍无效,Nginx日志显示请求/api/v1时尝试从/usr/share/nginx/html读取文件,未匹配到/api/v1的location规则
相关配置
Docker Compose配置
services: frontend: container_name: frontend depends_on: - backend build: context: frontend dockerfile: ./Dockerfile ports: - 80:80 environment: NODE_EVN: production networks: - app-network backend: container_name: backend depends_on: - db build: context: backend dockerfile: ./Dockerfile ports: - 8000:8000 environment: NODE_EVN: production DB_URL: mongodb://db/dbname networks: - app-network db: container_name: db image: mongo:latest ports: - 27017:27017 volumes: - dbname:/data/db networks: - app-network volumes: dbname: networks: app-network:
前端容器原Nginx配置
server { listen 80; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /api/v1/ { proxy_pass http://backend:8000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_redirect off; proxy_buffering off; proxy_cache off; } }
公司Nginx反向代理配置
location /myapp/ { proxy_pass http://<my vm IP-address>:80/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_redirect off; proxy_buffering off; proxy_cache off; }
问题原因
- 路径转发匹配错误:公司Nginx的
proxy_pass末尾带有斜杠,会将/myapp/后的路径直接拼接至目标地址,即用户访问/myapp/api/v1/xxx时,前端容器收到的请求是/api/v1/xxx,而非/myapp/api/v1/xxx。你修改前端Nginx配置为/myapp/api/v1/,导致无法匹配实际收到的请求路径,最终走了/的location规则去读取静态文件,返回404。 - 前端应用请求路径未适配:React应用部署在
/myapp/路径下,但未设置路由basename和API请求的基础路径,导致前端发起的API请求是/api/v1/xxx,而非/myapp/api/v1/xxx,直接绕过公司Nginx的代理规则,请求到VM的根路径下的/api/v1/,无法匹配到对应规则。
解决方案
1. 恢复前端容器的Nginx配置
保持原有的location /api/v1/规则不变,因为前端容器实际收到的请求就是/api/v1/开头的:
server { listen 80; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /api/v1/ { proxy_pass http://backend:8000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_redirect off; proxy_buffering off; proxy_cache off; } }
修改后重启frontend容器:docker-compose restart frontend
2. 调整React应用的路径配置
- 路由basename配置:在React路由中添加
basename="/myapp",确保前端路由适配/myapp/路径:// React Router v6示例 import { BrowserRouter } from 'react-router-dom'; <BrowserRouter basename="/myapp"> {/* 路由组件 */} </BrowserRouter> - API请求基础路径配置:将前端API请求的baseURL设置为
/myapp/api/v1,确保请求路径带/myapp前缀,经过公司Nginx转发后变为/api/v1,匹配前端容器的Nginx规则:// Axios配置示例 import axios from 'axios'; const api = axios.create({ baseURL: '/myapp/api/v1', });
3. 验证配置
- 访问
http://<公司域名>/myapp/,确认前端页面正常加载 - 发起API请求,检查浏览器网络请求路径为
/myapp/api/v1/xxx,且返回200响应 - 查看前端容器的Nginx日志,确认请求
/api/v1/xxx匹配到对应的location规则并转发至backend
内容的提问来源于stack exchange,提问作者lichb0rn
相关产品推荐
相关产品推荐

