1. 引言

在真实的企业开发中,将前端 Vue3 项目与后端 Java 项目通过 Docker 进行容器化部署,是保障环境一致性、实现快速交付与弹性伸缩的关键环节。本文将从零开始,带你完成一套贴近企业实践的部署方案,涵盖镜像构建、容器编排、挂载卷、网络通信等核心内容,全程使用 docker run 命令,不使用 Docker Compose。

2. 整体架构设计

在动手之前,我们先明确企业级部署的整体架构。一个典型的前后端分离项目,通常包含以下组件:

  • 前端服务:Nginx 承载 Vue3 构建后的静态资源,并反向代理后端 API。
  • 后端服务:Java 应用(Spring Boot 等)提供 RESTful API。
  • 数据库:MySQL 存储业务数据。
  • 缓存:Redis 提供缓存与会话管理。

所有容器通过自定义网络 net-gym 互联,并通过容器名互相访问。下面是整体架构图:

Docker 宿主机

客户端

Redis 容器

MySQL 容器

Java 容器

Nginx 容器

http://backend-gym:8088

HTTP

浏览器 / 移动端

静态资源

反向代理 /api

Spring Boot 应用

业务数据库

缓存

3. 环境准备

3.1 安装 Docker

首先,确保你的服务器或开发机上已安装 Docker。

# 验证 Docker 是否安装成功
docker --version

如果 Docker 尚未安装,可以参考我之前写的《Docker(1) Docker 安装全流程:从入门到生产实践》,里面有 Ubuntu、CentOS 等主流系统的详细安装步骤。建议使用 Ubuntu 24.04 LTS及以上。

企业项目中,我们通常将部署相关文件与代码仓库分离管理。建议的目录结构如下:

/usr/local/file/
├── frontend/
│   └── GymManagementSystem/     # 前端部署目录
│       ├── dist/                # 前端编译产物
│       └── nginx/
│           └── default.conf     # Nginx 配置
├── backend/
│   └── GymManagementSystem/     # 后端部署目录
│       ├── mars-admin.jar       # 后端 jar 包
│       └── application-prod.yml # 生产配置
└── mysql/
    ├── data/                    # MySQL 数据目录
    └── conf/                    # MySQL 配置目录

4. 前端 Vue3 项目部署

本章直接使用 docker run 命令启动 Nginx 容器,通过挂载卷将前端编译产物和 Nginx 配置挂载到容器中,无需编写 Dockerfile 和构建镜像。

4.1 创建所需文件夹

mkdir -p /usr/local/file/frontend/GymManagementSystem
mkdir -p /usr/local/file/frontend/GymManagementSystem/nginx

4.2 上传前端编译产物

将前端项目 npm run build 生成的 dist 目录上传到 /usr/local/file/frontend/GymManagementSystem/ 下。

4.3 编写 Nginx 配置

在 /usr/local/file/frontend/GymManagementSystem/nginx/ 目录下创建 default.conf:

server {
    listen 80;
    server_name _;
    root /usr/share/nginx/html;
    index index.html;

    # Vue/React history 路由,刷新 404 解决方案
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 7d;
    }

    # 前后端分离,代理后端接口,按需开启修改地址
    location /api/ {
        proxy_pass http://backend-gym:8088/;
        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;
    }
}

4.4 启动 Nginx 容器

docker run -d \
  --name nginx-GymManagementSystem \
  --restart unless-stopped \
  --network net-gym \
  -p 8081:80 \
  -v /usr/local/file/frontend/GymManagementSystem/dist:/usr/share/nginx/html:ro \
  -v /usr/local/file/frontend/GymManagementSystem/nginx/default.conf:/etc/nginx/conf.d/default.conf \
  nginx

说明:宿主机 8081 端口映射到容器 80 端口,访问 http://服务器IP:8081 即可打开前端页面。

5. 后端 Java 项目部署

本章直接使用 docker run 命令启动后端容器,通过挂载卷将 jar 包和配置文件挂载到容器中,无需编写 Dockerfile 和构建镜像。

5.1 创建所需文件夹

mkdir -p /usr/local/file/backend/GymManagementSystem/logs
mkdir -p /usr/local/file/mysql/data /usr/local/file/mysql/conf

5.2 启动 MySQL 容器

docker run -d \
  --name mysql-gym \
  --restart unless-stopped \
  --network net-gym \
  -p 3306:3306 \
  -v /usr/local/file/mysql/data:/var/lib/mysql \
  -v /usr/local/file/mysql/conf:/etc/mysql/conf.d \
  -e MYSQL_ROOT_PASSWORD="123456" \
  -e MYSQL_DATABASE="gym_system" \
  mysql:8.0

5.3 启动 Redis 容器

docker run -d \
  --name redis-gym \
  --network net-gym \
  -p 6379:6379 \
  redis:alpine

5.4 启动后端项目容器

将后端打包好的 mars-admin.jar 与 application-prod.yml 上传到 /usr/local/file/backend/GymManagementSystem/ 目录,然后启动:

docker run -d \
  --name backend-gym \
  --network net-gym \
  -p 8080:8088 \
  -e DB_HOST=mysql-gym \
  -e DB_PORT=3306 \
  -e DB_NAME=gym_system \
  -e DB_USERNAME=root \
  -e DB_PASSWORD=123456 \
  -e REDIS_HOST=redis-gym \
  -e REDIS_PORT=6379 \
  -v /usr/local/file/backend/GymManagementSystem/mars-admin.jar:/app/app.jar \
  -v /usr/local/file/backend/GymManagementSystem/application-prod.yml:/app/application-prod.yml \
  eclipse-temurin:17-jre-alpine \
  sh -c "java -Xms256m -Xmx512m -Djava.security.egd=file:/dev/./urandom -jar /app/app.jar --spring.profiles.active=prod"

说明:后端容器内部端口为 8088,映射到宿主机 8080。Nginx 通过容器名 backend-gym 在 net-gym 网络内访问后端 8088 端口。

7. 启动与验证

7.1 启动全部服务

按顺序执行以下命令启动全部容器:

# 1. 创建网络(已创建可跳过)
docker network create net-gym

# 2. 启动 MySQL
docker start mysql-gym

# 3. 启动 Redis
docker start redis-gym

# 4. 启动后端
docker start backend-gym

# 5. 启动前端 Nginx
docker start nginx-GymManagementSystem

# 查看所有容器运行状态
docker ps

7.2 验证服务可用性

# 验证前端页面
curl -I http://localhost:8081

# 验证后端健康检查接口
curl http://localhost:8080/api/health

# 验证 MySQL 连接
docker exec -it mysql-gym mysql -uroot -p -e "SELECT 1;"

# 验证 Redis 连接
docker exec -it redis-gym redis-cli ping

7.3 常见问题排查

问题现象可能原因解决方案
前端页面 404Nginx 配置错误检查 default.conf 的 try_files 配置
后端接口 502服务未启动或网络不通检查 docker ps 与容器日志 docker logs backend-gym
数据库连接失败密码不匹配或未初始化检查 -e MYSQL_ROOT_PASSWORD 与后端 DB_PASSWORD 是否一致
容器间无法通信未加入同一网络确认所有容器都使用 --network net-gym

8. 数据持久化与备份

8.1 挂载卷说明

本文方案中,以下数据均通过挂载卷持久化到宿主机:

服务容器路径宿主机路径用途
MySQL/var/lib/mysql/usr/local/file/mysql/data数据库文件
Redis/data未挂载(内存缓存)缓存数据
后端/app/app.jar/usr/local/file/backend/GymManagementSystem/mars-admin.jar后端 jar 包
后端/app/application-prod.yml/usr/local/file/backend/GymManagementSystem/application-prod.yml生产配置
Nginx/usr/share/nginx/html/usr/local/file/frontend/GymManagementSystem/dist前端静态资源
Nginx/etc/nginx/conf.d/default.conf/usr/local/file/frontend/GymManagementSystem/nginx/default.confNginx 配置

提示:如需 Redis 持久化,可在启动时增加 -v /usr/local/file/redis/data:/data 挂载参数。

11. 滚动更新与回滚

11.1 滚动更新

企业发布新版本时,使用以下流程实现零停机更新:

# 1. 构建新版本后端镜像(如有代码变更)
docker build -t myapp-backend:1.1.0 .

# 2. 停止并删除旧容器
docker stop backend-gym && docker rm backend-gym

# 3. 使用新镜像重新启动容器
docker run -d \
  --name backend-gym \
  --network net-gym \
  -p 8080:8088 \
  -e DB_HOST=mysql-gym \
  -e DB_PORT=3306 \
  -e DB_NAME=gym_system \
  -e DB_USERNAME=root \
  -e DB_PASSWORD=123456 \
  -e REDIS_HOST=redis-gym \
  -e REDIS_PORT=6379 \
  -v /usr/local/file/backend/GymManagementSystem/mars-admin.jar:/app/app.jar \
  -v /usr/local/file/backend/GymManagementSystem/application-prod.yml:/app/application-prod.yml \
  eclipse-temurin:17-jre-alpine \
  sh -c "java -Xms256m -Xmx512m -Djava.security.egd=file:/dev/./urandom -jar /app/app.jar --spring.profiles.active=prod"

11.2 快速回滚

# 回滚到上一版本:重新上传旧 jar 包后重启容器
docker stop backend-gym && docker rm backend-gym

# 重新执行 11.1 中的 docker run 命令即可

12. 总结

通过本文的完整实践,你已经掌握了使用 Docker 命令部署 Vue3 前端与 Java 后端企业级项目的方法。核心要点总结如下:

  • 自定义网络:通过 docker network create net-gym 实现容器间通过容器名通信。
  • 挂载卷持久化:保障数据库、上传文件等数据不因容器重建而丢失。
  • 环境变量外部化:敏感配置与代码分离,提升安全性。
  • 端口映射:宿主机端口与容器端口灵活映射,满足不同访问需求。
  • 容器生命周期管理:掌握 docker run、docker start、docker stop、docker rm 等核心命令。

这套方案可以直接应用于真实的企业项目交付,后续可根据业务规模引入 Kubernetes 进行更复杂的编排管理。

更多推荐