Docker Nginx反代Vue Vite及后端容器访问异常排查
问题根因
空白页由三个配置错误共同导致,和Docker网络连通性、Vite构建产物无关——你之前把前后端服务端口统一为80、加入同一Docker网桥的操作已经解决了最初的502问题,剩下的都是Nginx规则和配置路径的错误。
1. 边缘代理Nginx规则冲突
你在443端口的location /块中同时配置了本地静态资源规则和反向代理规则:
- 块内的
root /usr/share/nginx/html/、index index.html、try_files $uri $uri/ /index.html三行完全无效:运行反向代理的Nginx容器内没有任何前端静态文件,这些规则会优先拦截静态资源请求,返回404,浏览器拿不到JS/CSS自然渲染空白页。 - 你传递给前端容器的
Host头值为$host(公网域名),但前端容器内的Nginx没有配置对应域名的虚拟主机,会出现路由匹配异常。
修复方案
- 直接删除8081、8080两个多余的server块:这两个端口既没有映射到宿主机,也不会接收公网请求,留着只会产生规则冲突。
- 删除443端口
location /块内的本地静态资源相关三行配置,修改Host头传递值为$proxy_host,修正后的块内容如下:
location / { gzip off; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "origin"; proxy_pass http://docker-frontend/; proxy_redirect off; 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-Host $server_name; }
2. 前端容器Nginx配置用错
你当前Dockerfile中把边缘代理用的完整Nginx配置拷贝到了前端容器内,覆盖了前端容器Nginx的全局配置——这个配置里全是反代、SSL相关规则,根本不会正确服务容器本地的静态构建产物。
修复方案
单独给前端容器写一个静态服务专用的Nginx配置,命名为frontend.nginx.conf:
server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } }
修改前端Dockerfile,不要覆盖全局nginx.conf,只替换默认虚拟主机配置即可:
FROM node:lts-alpine as build-stage RUN mkdir -p /app WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:stable-alpine as production-stage RUN rm -rf /etc/nginx/conf.d/default.conf COPY ./frontend.nginx.conf /etc/nginx/conf.d/default.conf RUN rm -rf /usr/share/nginx/html/* COPY --from=build-stage /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
3. Vite配置冗余+路径问题
你配置里的publicPath是Vue CLI的专属配置项,Vite不会识别该字段;同时你设置的base: './'是相对路径,在反向代理场景下容易出现资源路径拼接错误,因为你的前端服务是挂载在域名根路径下的,用绝对路径更稳妥。
修复方案
删除无效的publicPath字段,把base值改为/:
import { fileURLToPath, URL } from 'url' import vue from '@vitejs/plugin-vue' import { defineConfig } from 'vite' import svgLoader from 'vite-svg-loader' export default defineConfig({ server: { port: 8081 }, plugins: [vue(), svgLoader()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, css: { preprocessorOptions: { scss: { implementation: require('sass'), additionalData: ` @import "./src/assets/scss/main.scss"; ` } } }, base: '/' })
验证流程
- 重新构建前端镜像,重启前端容器
- 重启边缘代理Nginx容器加载新配置
- 进入边缘代理Nginx容器,执行
curl http://frontend确认能返回index.html内容,再请求assets目录下的JS/CSS路径确认能正常返回静态资源,验证容器间通信正常 - 清空浏览器缓存后访问域名即可正常加载页面
补充说明:你之前添加的WebSocket升级头配置仅在代理Vite开发服务时需要,生产环境是预构建的静态文件,不需要加这几行配置;你在前端容器内看到的assets目录下带哈希后缀的JS/CSS是Vite的正常构建产物,不存在构建错误。
内容的提问来源于stack exchange,提问作者King Reload
相关产品推荐
相关产品推荐

