Docker 化部署 Spring Boot + Vue 全栈应用:从打包到容器化上线

Docker 化部署 Spring Boot + Vue 全栈应用:从打包到容器化上线

1. 引言

在现代软件开发中,容器化部署 已经成为主流。Docker 通过轻量级容器技术,解决了环境不一致、依赖冲突、部署复杂等问题。对于前后端分离项目(Spring Boot + Vue),使用 Docker 可以将前端、后端分别打包成镜像,并通过 docker-compose 一键启动整套应用,实现高效、可复用的交付。

本文将手把手带你:

  • ✅ 将 Spring Boot 应用打包成 Docker 镜像
  • ✅ 将 Vue 应用打包成 Nginx 镜像
  • ✅ 使用 Docker Compose 编排前后端服务
  • ✅ 配置网络、环境变量、数据持久化
  • ✅ 生产环境优化建议

无论你是个人开发者还是团队成员,都能通过本文轻松掌握全栈应用的容器化部署。


2. 整体架构流程图

容器编排
Docker构建
开发环境
Spring Boot 源码
mvn clean package

生成 jar
Vue 源码
npm run build

生成 dist
编写 Dockerfile

基于 OpenJDK
构建后端镜像

docker build -t backend
编写 Dockerfile

基于 Nginx
构建前端镜像

docker build -t frontend
docker-compose.yml
docker-compose up -d
应用运行


3. 准备工作

3.1 环境要求

组件 版本 说明
Docker 20.10+ 核心容器引擎
Docker Compose 2.20+ 多容器编排(已集成于 Docker 官方)
JDK 11 / 17 构建后端 jar
Node.js 16+ 构建前端 dist
Maven 3.6+ 构建后端(可选,也可用镜像内构建)

3.2 项目结构示例

复制代码
project/
├── backend/                 # Spring Boot 项目
│   ├── src/
│   ├── pom.xml
│   └── Dockerfile
├── frontend/                # Vue 项目
│   ├── src/
│   ├── package.json
│   ├── vue.config.js
│   └── Dockerfile
├── docker-compose.yml
└── nginx.conf              # 可选的 Nginx 自定义配置

4. 后端 Spring Boot 应用 Docker 化

4.1 打包 jar 文件

在项目根目录执行:

bash 复制代码
cd backend
mvn clean package -DskipTests

生成的 jar 位于 target/xxx.jar

4.2 编写 Dockerfile(多阶段构建优化)

创建 backend/Dockerfile

dockerfile 复制代码
# 第一阶段:构建(使用 Maven 镜像,可选)
FROM maven:3.8.4-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

# 第二阶段:运行
FROM openjdk:11-jre-slim
WORKDIR /app
# 从构建阶段复制 jar
COPY --from=builder /app/target/*.jar app.jar
# 暴露端口
EXPOSE 8080
# 启动命令(可配置外部参数)
ENTRYPOINT ["java", "-jar", "app.jar"]

说明:使用多阶段构建可减小镜像体积,因为最终镜像只包含 JRE 和 jar,不包括 Maven 和源代码。

4.3 构建镜像

bash 复制代码
docker build -t my-backend:1.0 ./backend

4.4 测试运行

bash 复制代码
docker run -d -p 8080:8080 --name backend-test my-backend:1.0

访问 http://localhost:8080/actuator/health(如果有监控端点)验证。


5. 前端 Vue 应用 Docker 化

5.1 构建静态文件

bash 复制代码
cd frontend
npm install
npm run build

生成 dist 目录,包含所有静态资源(HTML、CSS、JS)。

5.2 编写 Dockerfile(基于 Nginx)

创建 frontend/Dockerfile

dockerfile 复制代码
# 阶段1:构建(可选,如果宿主机已构建可直接复制)
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 阶段2:Nginx 服务器
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制自定义 Nginx 配置(可选)
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

如果宿主机已执行 npm run build,可以简化:

dockerfile 复制代码
FROM nginx:alpine
COPY ./dist /usr/share/nginx/html
EXPOSE 80

5.3 自定义 nginx.conf(解决 Vue Router history 模式 404 问题)

创建 frontend/nginx.conf

nginx 复制代码
server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # 可选:后端 API 代理(也可以由前端调用真实后端地址)
    location /api/ {
        proxy_pass http://backend:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

注意:如果使用代理,需要确保后端服务名在 docker-compose 中定义为 backend

5.4 构建前端镜像

bash 复制代码
docker build -t my-frontend:1.0 ./frontend

5.5 测试运行

bash 复制代码
docker run -d -p 80:80 --name frontend-test my-frontend:1.0

访问 http://localhost,应看到 Vue 首页。


6. 使用 Docker Compose 编排全栈应用

创建根目录下的 docker-compose.yml

yaml 复制代码
version: '3.8'

services:
  # 后端服务
  backend:
    image: my-backend:1.0
    container_name: backend
    build: ./backend               # 可动态构建
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/mydb?useSSL=false
    depends_on:
      - mysql
    networks:
      - app-network

  # 前端服务
  frontend:
    image: my-frontend:1.0
    container_name: frontend
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - app-network

  # 数据库(可选)
  mysql:
    image: mysql:8.0
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  mysql-data:

6.1 启动所有服务

bash 复制代码
docker-compose up -d

6.2 查看日志

bash 复制代码
docker-compose logs -f

6.3 停止并删除容器

bash 复制代码
docker-compose down -v   # -v 会删除数据卷(注意数据丢失)

7. 生产环境优化建议

7.1 镜像体积优化

  • 后端使用 eclipse-temurin:17-jre-alpineopenjdk:11-jre-slim 替代完整 JDK。
  • 前端使用 nginx:alpine,体积仅 20MB 左右。
  • 多阶段构建去除构建工具和源码。

7.2 配置外部化

  • 使用环境变量覆盖 Spring Boot 配置。
  • 敏感信息(数据库密码)通过 Docker secrets 或环境变量注入,不要写死在镜像中。

7.3 健康检查

docker-compose.yml 中加入健康检查:

yaml 复制代码
backend:
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
    interval: 30s
    timeout: 10s
    retries: 3

7.4 日志管理

  • 将容器日志输出到 stdout,由 Docker 日志驱动收集。
  • 生产环境可配置 logging 驱动为 json-filefluentd

7.5 反向代理与 HTTPS

  • 在前端 Nginx 中配置 SSL 证书。
  • 可再增加一个 nginx-proxy 服务统一入口。

8. 常见问题与排查

问题 可能原因 解决方案
前端访问后端 API 出现跨域 前后端不同端口 配置 Nginx 反向代理,或后端添加 CORS 过滤器
Vue 路由刷新 404 history 模式下未配置 try_files 修改 nginx.conf,添加 try_files $uri $uri/ /index.html;
后端容器无法连接数据库 数据库 host 配置错误 使用 docker-compose 服务名(如 mysql)作为主机名
镜像构建失败 Dockerfile 中 COPY 路径错误 检查上下文路径,确认文件存在
端口被占用 宿主机端口已被使用 修改 ports 映射到不同宿主机端口

9. 部署全景流程图



编写 Dockerfile
构建镜像
编写 docker-compose.yml
docker-compose up -d
测试访问
是否正常?
推送到镜像仓库

如 Harbor/Docker Hub
查看日志

调整配置
生产服务器拉取镜像并运行


10. 总结

通过 Docker 容器化部署 Spring Boot + Vue 全栈应用,我们可以获得以下收益:

  • 环境一致性:开发、测试、生产环境完全相同,杜绝"在我机器上能跑"问题。
  • 快速部署 :一条 docker-compose up 命令即可启动所有服务。
  • 可扩展性:轻松增加容器副本,结合 Kubernetes 实现弹性伸缩。
  • 资源隔离:每个服务运行在独立的容器中,互不干扰。

最佳实践回顾

  • 前端使用 Nginx 镜像并提供自定义配置解决路由问题。
  • 后端使用多阶段构建减小体积。
  • 使用 Docker Compose 编排,定义网络和数据卷。
  • 将配置(如数据库连接)通过环境变量传递,避免硬编码。

下一步:可以将镜像推送到私有仓库(如 Harbor),并配合 CI/CD(GitLab CI / Jenkins)实现自动化构建和部署。

相关推荐
会编程的土豆12 小时前
Docker 里面的镜像(Image)和容器(Container)到底是什么
运维·docker·容器
r-t-H12 小时前
KVM虚拟化与Docker基础实践-第三章
linux·运维·nginx·docker·容器
一只大袋鼠13 小时前
SpringBoot 入门学习笔记(三)Web 开发下篇
spring boot·笔记·学习
西凉的悲伤13 小时前
SpringBoot RestTemplate 介绍
java·spring boot·后端·resttemplate
IT_Octopus21 小时前
Spring Boot 实战:@PostConstruct + Caffeine 缓存初始化与定时刷新
spring boot·后端·缓存
Niliuershangba1 天前
Docker Desktop 部署 ChestnutCMS 全流程:从零搭建企业级 CMS 开发环境
运维·docker·容器
zb200641201 天前
Laravel7.x十大核心特性解析
spring boot·后端·laravel
他们叫我阿冠1 天前
Day5学习--SpringBoot详解
spring boot·后端·学习
独泪了无痕1 天前
CryptoJS:数据安全的JavaScript加密利器
前端·vue.js·node.js