从零开始!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。

相关推荐
我命由我123452 小时前
Element Plus 问题:选择框表单校验没有触发
开发语言·前端·javascript·html·ecmascript·html5·js
bug攻城狮2 小时前
为什么 Spring Boot 要单元测试?
spring boot·后端·单元测试
optimistic_chen2 小时前
【Vue3入门】vue-router 路由管理
前端·javascript·vue.js·路由·router
DJ斯特拉2 小时前
Docker基本使用
运维·docker·容器
无名-CODING2 小时前
从零开始!Vue3+SpringBoot前后端分离项目Docker部署实战(中):Spring Boot后端与Docker Compose串联
spring boot·后端·docker
柯儿的天空2 小时前
WebGPU全面解析:新一代Web图形与计算API
前端·chrome·microsoft·前端框架·chrome devtools·view design
捕捉一只前端小白2 小时前
cpolar内网穿透以及微信小程序域名设置
前端·vue.js·微信小程序·小程序
wuhen_n2 小时前
ESLint + Prettier + Husky + lint-staged:建立自动化的高效前端工作流
前端·javascript·vue.js