React-Vite应用NGINX反向代理静态文件访问配置问题排查
我正在开发基于Vite的React应用,通过Docker容器部署,使用NGINX作为反向代理提供HTTPS访问。相关配置文件如下:
Dockerfile
# Build stage FROM node:18-alpine AS build # Set the working directory in the container WORKDIR /app # Copy package.json and package-lock.json to install dependencies COPY package*.json ./ # Install project dependencies RUN npm install # Copy the rest of the project files COPY . . # Build the application RUN npm run build # Production stage FROM node:18-alpine WORKDIR /app # Install serve globally RUN npm install -g serve # Copy only the build folder COPY --from=build /app/dist ./dist EXPOSE 97 CMD ["serve", "-s", "dist", "-l", "97"]
nginx.cfg
events { worker_connections 1024; # Maximum number of connections accepted by each worker } http { server { listen 443 ssl; server_name my_domain_here; http2 on; ssl_certificate /etc/nginx/ssl/ssl_certificate.crt; ssl_certificate_key /etc/nginx/ssl/ssl_certificate.key; location /photo/ { proxy_pass http://prueba_front:97/photo/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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; proxy_read_timeout 90s; proxy_connect_timeout 90s; proxy_send_timeout 90s; send_timeout 90s; } } }
docker-compose.yml
services: nginx: image: nginx:latest ports: - "443:443" volumes: - ./nginx.cfg:/etc/nginx/nginx.conf - ./ssl:/etc/nginx/ssl networks: - poc_probe prueba_front: build: context: ./app/front dockerfile: Dockerfile ports: - "97:97" networks: - poc_probe networks: poc_probe: driver: bridge
vite.config.js
import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; // Desarrollo export default defineConfig({ base: "/", // Base URL para la aplicación plugins: [react()], build: { outDir: 'dist', // Directorio de salida para la construcción rollupOptions: { // Configuración adicional de Rollup si es necesaria } }, preview: { port: 5173, strictPort: true, }, server: { port: 5173, strictPort: true, host: true, origin: "http://0.0.0.0:8080", }, });
访问https://my_domain/photo/时,提示dist文件夹中的静态.js和.css文件找不到,但进入端口97的容器后可确认文件存在;使用私有IP访问应用正常,但通过HTTPS反向代理访问时出现该错误。已确认构建时dist文件夹生成了静态文件,尝试配置NGINX反向代理但未达预期,因刚接触NGINX可能遗漏配置。
NGINX配置中哪些问题导致静态文件无法通过反向代理正常访问?有哪些调试方法?
NGINX配置中的问题
静态资源请求未被代理
当前NGINX仅配置了/photo/路径的代理,但React应用加载的静态资源(如/assets/index.xxx.js)是根路径开头的请求,这些请求不会匹配/photo/的location规则,导致NGINX直接返回404。proxy_pass路径的斜杠错误
你的proxy_pass设置为http://prueba_front:97/photo/(末尾带斜杠),会把/photo/xxx的请求转发为http://prueba_front:97/photo/xxx,但实际React应用部署在根路径(base: "/"),后端serve服务期望的请求路径是/xxx而非/photo/xxx,导致静态资源找不到。缺少路径重写规则
没有对/photo/开头的请求做路径重写,前端服务无法识别带/photo/前缀的资源路径。
修正后的NGINX配置示例
events { worker_connections 1024; } http { server { listen 443 ssl; server_name my_domain_here; http2 on; ssl_certificate /etc/nginx/ssl/ssl_certificate.crt; ssl_certificate_key /etc/nginx/ssl/ssl_certificate.key; location /photo/ { proxy_pass http://prueba_front:97; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $proxy_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_read_timeout 90s; proxy_connect_timeout 90s; proxy_send_timeout 90s; send_timeout 90s; # 重写路径,去掉开头的/photo/前缀 rewrite ^/photo/(.*)$ /$1 break; } } }
同时需要调整Vite的base配置,在vite.config.js中将base改为"/photo/",这样构建后的静态资源路径会自动带上/photo/前缀,匹配NGINX的代理规则。
调试方法
查看NGINX访问日志
进入NGINX容器,查看/var/log/nginx/access.log,里面会记录所有请求的路径、状态码,通过404状态码对应的请求路径,能快速定位未被正确代理的资源。
执行命令:docker exec -it <nginx容器ID> cat /var/log/nginx/access.log查看NGINX错误日志
查看/var/log/nginx/error.log,里面会记录配置错误、代理连接失败等关键信息,帮助排查深层问题。
执行命令:docker exec -it <nginx容器ID> cat /var/log/nginx/error.log直接测试后端服务
在NGINX容器内用curl测试前端服务的资源是否可访问,比如:curl http://prueba_front:97/assets/index.xxx.js,确认资源本身没问题后,再测试curl https://my_domain/photo/assets/index.xxx.js对比结果。检查前端构建后的资源路径
进入前端容器,查看dist/index.html中的静态资源引用路径,确认路径是否和代理规则匹配。比如如果base设为"/",资源路径是/assets/xxx,浏览器会直接请求根路径的资源,不会走/photo/的代理。启用NGINX调试日志
在NGINX配置的http块中添加:error_log /var/log/nginx/debug.log debug;重启NGINX后,会生成详细的请求处理日志,能清晰看到请求被哪个location匹配、转发路径是什么。
内容的提问来源于stack exchange,提问作者Alexander idid

