从零开始!Vue3+SpringBoot前后端分离项目Docker部署实战(下):Vue前端Nginx反代与致命坑点盘点

📝 前言

这是本系列的终篇,也是很多人在第一次部署个人全栈项目时,踩坑最多、最容易令人绝望的一个环节 ------ 前端打包部署。

在本地开发 Vue/Vite 或 React 时,我们在 request.js 里写一个 http://localhost:8080/api 就觉得高枕无忧了。但一把构建丢到服务器上,才猛然发现接口死活都不通(抛出 ERR_CONNECTION_REFUSED 或是 CORS 跨域错误)。而且在国内服务器经常遇到 npm install 卡死抛错 ETIMEDOUT

这篇博客,我就带大家一一跨越这些"致命天坑",使用最佳实践:前端多阶段构建 + Nginx 静态驱动 + Nginx 反向代理解决跨域连通


🏔️ 第一坑:国内构建 npm install 超时天坑

如果你的项目是在阿X云、腾X云等国内机房服务器里构建的,不要想着直接 npm i,一定要在 Dockerfile 里配置国内强力镜像及代理。

针对由于网络不好引发的依赖丢失(比如经常发现 vite 构建丢了依赖),可以在 frontend/vue/Dockerfile 这么写:

dockerfile 复制代码
# ---- 阶段 1:构建阶段 ----
FROM docker.m.daocloud.io/node:18-alpine AS build
WORKDIR /app

# 先单独拷贝打包信息,利用Docker缓存机制
COPY package.json package-lock.json* ./

# 【关键配置】设置 npm 环境变量使用国内源进行极速下载
ENV NPM_CONFIG_REGISTRY=https://registry.npmmirror.com/

# 如果出现 npm gyp 或编译依赖问题,安装 python 与 make (可选,看项目库)
# RUN apk add --no-cache python3 make g++

# 强制安装避免警告造成的意外失败
RUN npm install --production=false --omit=dev=false --loglevel verbose

# 规避偶发的 vite 或 rollup 二进制文件缺失
RUN npm install -g vite@4.5.14

# 拷贝全部源码
COPY . .

# 通过传参覆盖内置环境变量,使得所有 axios api 配置变成空前缀 (下面重点讲)
ARG VITE_API_BASE_URL=""
ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}

# 使用 npx 显式打包,避免软链丢失引起的 command not found 错误
RUN npx vite build

# ---- 阶段 2:运行阶段(Nginx) ----
FROM docker.m.daocloud.io/nginx:alpine
# 将产物转移进 Nginx 默认目录
COPY --from=build /app/dist /usr/share/nginx/html
# 覆盖我们的专属 Nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

⚠️ Linux 的大小写敏感天坑

这里经常会面临一个很容易忽视的报错:

本地 Windows 下,你从 @/components/Layout/ 导入了一个文件,但在目录里文件夹叫 @/components/layout/!这在本地是没问题的,但因为基于 alpine Linux 的容器是严格区分大小写的! 打包直接就会抛出 Failed to resolve import 的死循环中,一定去你的源代码里检查大小写匹配!


🔄 第二招:Nginx 配置与动态反向代理

为了不让我们的浏览端(用户客户端)直接访问 SpringBoot (跨域灾难),我们直接用前端的同一个服务 Nginx 拦截对 /api 开头的请求,然后转发到刚才的中篇的容器里。

frontend/vue/nginx.conf 编写:

nginx 复制代码
server {
    listen 80;
    server_name localhost;

    # 这里处理单页应用的路由回退,如果使用 Vue Router 的 history 模式,必写这部分
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

    # Nginx 拦截 /api 动态反向代理到局域网内的后端容器!
    location /api/ {
        # 注意此处的 project001-backend 是 Docker-compose 的服务名!
        proxy_pass http://project001-backend:8080/api/;
        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;
    }

    # 代理 /uploads 处理静态文件的回放上传
    location /uploads/ {
        proxy_pass http://project001-backend:8080/uploads/;
    }
}

💣 最恐怖神坑:写死的默认 localhost:8080 导致拒收连接

如果你部署完发现页面出来了,但是点击登录,控制台报错:ERR_CONNECTION_REFUSED http://localhost:8080/api/auth/login

不要去服务器上找 8080 这个端口!由于前端跑在客户浏览器里(也就是你的个人电脑游览器而不是云主机),它拼装并去请求你"个人电脑"的 8080 端口,那它怎么可能连的上远在云服务器上的真实后端呢?

最佳解决方案:

  1. 检查前端源码里的 src/api/request.js 或者 Vite 配置(.env.production);
  2. 绝对不能使用 http://localhost:8080 做为保底参数;
  3. 将前端请求配置改为:baseURL: import.meta.env.VITE_API_BASE_URL || ''(也就是相对路径)。
  4. 结合 Docker-compose 参数:
yaml 复制代码
  project001-frontend:
    build:
      context: ./frontend/vue
      args:
        # 在这里把前缀设为空,编译出来的 JS 因为前缀空,默认会打往本域的 /api/...
        # 然后本域的 80 Nginx 就会通过反向代理吃掉它扔给后端!
        VITE_API_BASE_URL: ""
    container_name: project001-frontend
    ports:
      - "80:80"

最后,遇到缓存问题:即便部署对了,务必在 Chrome 浏览器点右键:强制清除缓存并硬性重新加载浏览器。前端旧的打包 JS 带毒太严重。


🎉 最后:One-Command Deploy

当你排清了上述坑,此时在你的服务器项目根目录只需要轻轻敲下一句:

bash 复制代码
docker rm -f $(docker ps -aq) && docker compose up -d --build

然后甩出你的这台虚拟机的公网 IP ,发给小伙伴:
"哎,朋友,来看看我刚上线的全栈系统爽不爽?"

一切就这么完成了!完结撒花。


欢迎点赞收藏评论,这是我从 0 到 1 上线真实项目的泣血总结!希望这套体系能直接助你拿下 Offer。

相关推荐
ai产品老杨1 天前
GB28181与RTSP全协议兼容之道:基于Docker与微服务架构的AI视频中台架构解析(附源码交付方案)
docker·微服务·架构
candyTong1 天前
一觉醒来,大模型就帮我排查完页面性能问题
前端·javascript·架构
魔术师Grace1 天前
我给 AI 做了场入职培训
前端·程序员
Java开发的小李1 天前
SpringBoot + Redis 实现分布式 Session 共享(解决多实例登录状态丢失问题)
spring boot·redis·分布式
玩嵌入式的菜鸡1 天前
网页访问单片机设备---基于mqtt
前端·javascript·css
前端一小卒1 天前
我用 Claude Code 的 Superpowers 技能链写了个服务,部署前差点把服务器搞炸
前端·javascript·后端
滑雪的企鹅.1 天前
HTML头部元信息避坑指南大纲
前端·html
一拳不是超人1 天前
老婆天天吵吵要买塔罗牌,我直接用 AI 2 小时写了个在线塔罗牌
前端·ai编程
阿丰资源1 天前
SpringBoot+Vue实战:打造企业级在线文档管理系统
vue.js·spring boot·后端
excel1 天前
如何解决 Nuxt DevTools 中关于 unstorage 包的报错
前端