Docker与Nginx模板配置下Proxy pass出现404错误求助
Nginx反向代理/api路径返回404(Docker容器环境,Vite dev模式正常)
问题核心
本地通过docker-compose up --build -d启动前端容器后,访问localhost:3000/api/health返回404 Not Found,但使用npm run dev(Vite开发模式)启动前端时,该接口可正常访问;相同配置在staging环境能正常运行,已尝试多种斜杠组合调整仍无效。
环境配置
nginx.conf.template配置
upstream backend { server localhost:5003; } server { listen 3000; server_name localhost; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://localhost:5003/; } location / { try_files $uri $uri/ /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
注:已添加末尾斜杠,也尝试过多种斜杠组合均无效,该文件原为模板配置,现已硬编码部分内容。
Dockerfile配置
# Use the official Node.js runtime as the base image FROM node:18.19 AS build # Set the working directory in the container WORKDIR /usr/src/app # Copy package.json and package-lock.json to the working directory COPY package*.json ./ # Install dependencies RUN npm ci # Copy the entire application code to the container COPY . . # Build the React app for production RUN npm run build FROM nginx:1.25.3-alpine # Copy the built React app to Nginx's web server directory COPY --from=build /usr/src/app/dist /usr/share/nginx/html COPY nginx.conf.template /etc/nginx/templates/default.conf.template # Start Nginx when the container runs CMD ["nginx", "-g", "daemon off;"]
Docker Compose文件
services: frontend: container_name: frontend env_file: .env restart: always ports: - 3000:3000
vite.config.js配置
import { defineConfig, loadEnv } from "vite"; import react from "@vitejs/plugin-react-swc"; import svgr from "vite-plugin-svgr"; // https://vitejs.dev/config/ export default ({ mode }) => { const env = loadEnv(mode, process.cwd(), ""); return defineConfig({ plugins: [ react(), svgr({ svgrOptions: { // svgr options }, }), ], optimizeDeps: { exclude: ["js-big-decimal"], }, test: { globals: true, environment: "jsdom", }, server: { watch: { usePolling: true, }, host: true, strictPort: true, port: env.FRONTEND_HTTP_PORT, proxy: { "/api": { target: env.BACKEND_SERVICE_URL, changeOrigin: true, }, }, }, }); };
关键排查点与解决方案
1. Docker容器网络隔离问题(核心原因)
Vite开发模式运行在宿主机,此时localhost:5003指向宿主机上的后端服务;但前端Docker容器内的localhost指向容器自身,而非宿主机,因此Nginx无法访问到宿主机的后端服务,返回404。
针对不同后端部署场景的修复:
后端运行在宿主机:
修改Nginx配置中的proxy_pass目标,替换为宿主机的可访问IP,或者使用Docker提供的特殊域名:- Windows/macOS:直接用
host.docker.internal代替localhostlocation /api/ { proxy_pass http://host.docker.internal:5003/; } - Linux:需要在docker-compose.yml中添加宿主机映射,再使用
host.docker.internal
同时修改Nginx的proxy_pass为services: frontend: container_name: frontend env_file: .env restart: always ports: - 3000:3000 extra_hosts: - "host.docker.internal:host-gateway"http://host.docker.internal:5003/
- Windows/macOS:直接用
后端运行在另一个Docker容器:
确保前端和后端容器处于同一个Docker网络,然后用后端容器的服务名/容器名代替localhost。比如后端服务名为backend,则修改Nginx配置:upstream backend { server backend:5003; # 这里用后端服务名 } location /api/ { proxy_pass http://backend/; # 或者直接用http://backend:5003/ }并在docker-compose.yml中添加网络配置,将前后端加入同一网络:
networks: app-network: driver: bridge services: frontend: container_name: frontend env_file: .env restart: always ports: - 3000:3000 networks: - app-network backend: # 后端的配置 networks: - app-network
2. 验证配置有效性
修改配置后,重新构建并启动容器:
docker-compose down && docker-compose up --build -d
进入前端容器,测试后端连通性:
docker exec -it frontend curl http://host.docker.internal:5003/health # 对应宿主机后端 # 或 docker exec -it frontend curl http://backend:5003/health # 对应容器后端
如果curl能返回正常响应,说明网络连通,此时访问localhost:3000/api/health即可正常返回。
3. 其他可能的优化
- 既然配置了
upstream backend,建议直接使用http://backend/作为proxy_pass目标,而非重复写localhost:5003,便于后续维护。 - 检查后端服务是否正常监听5003端口,且防火墙未限制该端口的访问。
内容的提问来源于stack exchange,提问作者SinByCos
相关产品推荐
相关产品推荐

