Loading...

文章背景图

Spring Boot + React 毕业设计部署实战:Docker Compose 一键上线 VPS

2026-04-30
1
-
- 分钟
|

前言

毕业设计做了一个基于 Spring Boot 3 + React 19 的前后端分离在线书店系统,功能涵盖用户认证、购物车、订单、支付、AI 推荐等完整电商链路。本地开发没问题,但要真正部署到服务器上,还是踩了不少坑。

本文记录从零开始,将项目通过 Docker Compose 部署到阿里云 ECS(1.6GB 内存)的完整过程。

技术架构

层级技术栈
后端Spring Boot 3.2.2 + Java 21 + MySQL 8.0 + JPA
前端React 19 + TypeScript + Vite 7 + Tailwind CSS + Ant Design
部署Docker Compose + Nginx 反向代理
服务器阿里云 ECS Debian 13, 1.6GB RAM, 10GB 磁盘

Docker Compose 架构

三个容器,各司其职:

用户浏览器 → :8088 (Nginx 容器)
                ├── /          → React SPA (静态文件)
                ├── /api/*     → Spring Boot 后端 (:8080)
                ├── /swagger/* → Swagger UI
                └── /uploads/* → 图片资源
                     ↕
              MySQL 8.0 容器 (:3306 仅本地)

部署步骤

1. 准备 Dockerfile

后端 Dockerfile — 多阶段构建,Maven 编译 + JRE 运行:

# 构建阶段
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn clean package -DskipTests -B

# 运行阶段
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
CMD ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

前端 Dockerfile — Node 构建 + Nginx 托管:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

2. 编写 docker-compose.yml

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: online_bookstore
    ports:
      - "127.0.0.1:3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

  backend:
    build: ./backend
    depends_on:
      mysql:
        condition: service_healthy
    environment:
      DB_URL: jdbc:mysql://mysql:3306/online_bookstore
      JWT_SECRET: ${JWT_SECRET}
      SPRING_PROFILES_ACTIVE: dev
      EMAIL_MOCK: "true"
      JAVA_OPTS: -Xms256m -Xmx512m
    volumes:
      - uploads_data:/app/uploads

  frontend:
    build: ./frontend
    ports:
      - "8088:80"
    depends_on:
      - backend

3. 一键启动

cd /opt/project_library
docker compose up -d --build

首次构建约 5-10 分钟(Maven 下载依赖 + npm install)。启动后 DataInitializer 自动填充 49 本图书、10 个用户、9 个示例订单。

踩坑记录与 Bug 修复

Bug 1:首页板块返回 401

现象:未登录用户访问 /api/home/* 全部返回 401 Unauthorized。

原因:SecurityConfig 中没有放行 /api/home/**,被 .anyRequest().authenticated() 拦截。

修复:在 SecurityConfig.javafilterChain 中添加:

.requestMatchers(HttpMethod.GET, "/api/home/**").permitAll()

Bug 2:删除优惠券 FK 约束报错

现象:管理员删除已领取的优惠券时,MySQL 报外键约束冲突。

原因user_coupons 表引用 coupons,没有级联删除。

修复:在 CouponService.deleteCoupon() 中,先删关联记录再删优惠券:

userCouponRepository.deleteByCouponId(id);
couponRepository.deleteById(id);

Bug 3:OpenAPI 文档重定向丢失端口

现象/v3/api-docs 301 重定向到 http://localhost/v3/api-docs/(丢失 :8088 端口)。

原因:Spring Boot 的 Tomcat 重定向使用 Host 头构造 URL,经过 Nginx 反代后端口信息丢失。

修复:两个改动 —

  1. 后端 application.properties 添加 spring.mvc.forward-headers-strategy=native
  2. 前端 nginx.conf 添加精确匹配:location = /v3/api-docs { proxy_pass ... }

Bug 4:DataInitializer 重启崩溃循环

现象:后端不断重启,日志报 Duplicate entry for key 'reviews.uk_review_user_book'

原因:DataInitializer 每次重启都插入 reviews,但没有防重复检查(orders 和 coupons 都有 count() == 0 检查,reviews 漏了)。

修复:添加 long existingReviewCount = reviewRepository.count(); 守卫条件。

Bug 5:购物车序列化崩溃

现象:购物车接口返回 500,Hibernate 懒加载代理无法序列化。

修复:在 CartItem.java@JsonIgnoreProperties 中添加 "hibernateLazyInitializer"

Bug 6:图片上传 404

现象:头像和封面图片返回 404。

原因:nginx 的正则 ~* \.(png|jpg|...)$ 优先级高于前缀 location /uploads/

修复:给 /uploads/^~ 优先匹配。

Mock 模式测试

系统支持三种 Mock 模式,答辩演示时无需真实第三方服务:

功能Mock ONMock OFF
邮箱验证码返回固定验证码 123456需要 SMTP 配置
AI 推荐返回预设推荐结果需要 OpenRouter API Key
支付宝支付模拟支付成功需要沙箱密钥

通过环境变量 EMAIL_MOCK=true/false 切换,重启后端即可生效。

最终验证结果

全面测试 90+ 个 API 端点,通过率 99%:

  • ✅ 认证(登录/注册/验证码)
  • ✅ 图书 CRUD + 搜索 + 分类
  • ✅ 购物车 + 订单 + 支付
  • ✅ 收藏 + 评价 + 浏览历史
  • ✅ 积分签到 + 优惠券
  • ✅ 管理后台仪表盘 + 数据导出
  • ✅ 首页板块公开访问
  • ✅ Swagger / OpenAPI 文档
  • ✅ 权限控制(401/403)

总结

1.6GB 内存的 VPS 完全可以跑起前后端分离项目,关键是 Docker Compose 让部署变得可重复、可维护。最大的收获不是部署本身,而是在过程中发现并修复了 6 个系统 Bug — 这些在本地开发时完全没暴露出来。

项目地址GitHub - project_library

评论交流

文章目录