# SmartClean 自动化部署使用手册 ## 概述 本项目提供两套独立的自动化部署方案,可同时使用、互不干扰: | 方案 | 目录 | 适用场景 | 依赖 | |------|------|---------|------| | **远程服务器部署** | `deploy/remote/` | 部署到 182 测试/生产服务器 | SSH 免密登录 | | **Docker 本机模拟** | `deploy/docker/` | 本机模拟完整生产环境 | Docker Desktop | --- ## 现状分析 ### 当前部署方式 | 环节 | 现状 | 问题 | |------|------|------| | **构建** | 本地执行 `build.sh`,手动触发 | 已自动化,含飞书通知 | | **上传** | 手动 SCP 或 FTP 上传到 182 服务器 | 无标准化流程,依赖个人操作习惯 | | **部署** | SSH 登录服务器,手动替换文件、重启服务 | 步骤多、易出错、无操作记录 | | **回滚** | 无备份机制,出问题需手动找旧版本 | 无法快速回滚,故障恢复时间长 | | **通知** | 构建结果有飞书通知,部署结果无通知 | 团队无法感知部署状态 | | **环境一致性** | 服务器环境手动搭建维护 | 本地与服务器环境可能不一致 | ### 现有脚本 | 脚本 | 用途 | 覆盖范围 | |------|------|---------| | `build.sh` | 本地构建(Maven + npm),支持分模块构建,含飞书通知 | 仅构建,不含部署 | | `start.sh` | 本地启动开发环境(mvn spring-boot:run + npm run dev) | 仅本地开发,非生产部署 | ### 现有流程 vs 新方案对比 ``` 现有流程(5 步手动操作,约 10-15 分钟): ┌──────────┐ 手动 ┌──────────┐ 手动 ┌──────────┐ 手动 ┌──────────┐ │ build.sh │ ───────→ │ SCP 上传 │ ───────→ │ SSH 替换 │ ───────→ │ 手动重启 │ │ 本地构建 │ │ 到服务器 │ │ 文件 │ │ 服务 │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ✅ 已自动化 ❌ 手动 ❌ 手动 ❌ 手动 ✅ 有飞书通知 ❌ 无记录 ❌ 无备份 ❌ 无健康检查 方案一 — 远程部署(1 条命令,全自动): ┌──────────────────────────────────────────────────────────────────────┐ │ deploy/remote/deploy.sh web │ │ 构建 → 备份 → 上传 → 重启 → 健康检查 → 飞书通知(失败自动回滚) │ └──────────────────────────────────────────────────────────────────────┘ 方案二 — Docker 部署(1 条命令,全自动): ┌──────────────────────────────────────────────────────────────────────┐ │ deploy/docker/deploy.sh web │ │ 镜像构建 → 容器替换 → 健康检查 → 飞书通知(失败自动回滚) │ └──────────────────────────────────────────────────────────────────────┘ ``` ### 新方案解决的问题 | 现状痛点 | 方案一(远程部署) | 方案二(Docker) | |----------|------------------|-----------------| | 手动上传、易传错 | SCP 自动传输,路径固定 | 不需要传输,镜像自包含 | | 无备份,无法回滚 | 每次部署自动备份,一键回滚 | 基于镜像 tag 回滚 | | 部署步骤多、易遗漏 | 一条命令完成全部步骤 | 一条命令完成全部步骤 | | 团队不知道谁部署了什么 | 飞书通知含版本/分支/操作人 | 飞书通知含版本/分支 | | 部署后不确认是否成功 | 自动健康检查,失败自动回滚 | 自动健康检查,失败自动回滚 | | 新人不知道怎么部署 | 看文档执行一条命令即可 | 一键启动完整环境 | --- ## 落地调整工作清单 ### 方案一(远程部署)落地前需要做的事 #### 一次性准备工作 | # | 任务 | 说明 | 负责人 | 耗时预估 | |---|------|------|--------|---------| | 1 | **配置 SSH 免密登录** | 本机生成密钥,`ssh-copy-id` 到 182 服务器 | 开发者 | 5 分钟 | | 2 | **确认服务器目录结构** | 登录 182 确认 Tomcat 实际安装路径、Nginx 配置路径、Task JAR 存放路径 | 开发者 | 10 分钟 | | 3 | **修改 config.sh** | 将 `TOMCAT_HOME`、`NGINX_HTML` 等路径改为服务器实际路径 | 开发者 | 5 分钟 | | 4 | **执行 setup 初始化** | `deploy/remote/deploy.sh setup` 创建标准目录 + 上传重启脚本 | 开发者 | 2 分钟 | | 5 | **调整重启脚本** | 根据服务器实际情况微调 `restart-web.sh` / `restart-task.sh`(如 Tomcat 启停方式、Task 服务的 JVM 参数) | 开发者 | 15 分钟 | | 6 | **首次全量部署测试** | 执行 `deploy/remote/deploy.sh` 验证全流程跑通 | 开发者 | 10 分钟 | #### 需确认的服务器信息 在落地之前,请先 SSH 到 182 服务器确认以下信息,并更新到 `config.sh`: ```bash # 登录服务器后执行以下命令,记录输出 # 1. Tomcat 安装路径 find / -name "catalina.sh" -type f 2>/dev/null # 将结果的父目录的父目录填入 TOMCAT_HOME # 2. Nginx 前端文件路径 nginx -T 2>/dev/null | grep "root " # 将 root 路径填入 NGINX_HTML # 3. Task 服务当前运行方式 ps -ef | grep "intellectual-task" # 确认 JAR 名称、启动参数,更新 TASK_JAR_NAME 和 TASK_JVM_OPTS # 4. 当前 WAR 包位置 find / -name "ROOT.war" -type f 2>/dev/null # 5. Java 版本 java -version ``` ### 方案二(Docker 本机模拟)落地前需要做的事 | # | 任务 | 说明 | 负责人 | 耗时预估 | |---|------|------|--------|---------| | 1 | **安装 Docker Desktop** | 如未安装,从官网下载安装 | 开发者 | 10 分钟 | | 2 | **确认端口无冲突** | 确保 8180/18095/18097/3307/6380 未被占用,如有冲突在 `.env` 中调整 | 开发者 | 2 分钟 | | 3 | **检查 SQL 初始化脚本** | 确认 `sql/` 目录下有完整的建库建表 SQL(Docker MySQL 首次启动会自动导入) | 开发者 | 5 分钟 | | 4 | **首次全量部署测试** | 执行 `deploy/docker/deploy.sh`,首次需下载基础镜像 + 编译,耗时较长 | 开发者 | 20-30 分钟 | | 5 | **验证前端 API 代理** | 确认 Nginx 的 `/api/` 反代规则与前端实际请求路径匹配(当前前端直接请求后端,无 `/api` 前缀,可能需要调整 `nginx.conf`) | 开发者 | 10 分钟 | #### 可能需要的代码调整 | 调整项 | 原因 | 影响范围 | |--------|------|---------| | **前端 .env.docker**(可选) | Docker 环境中前端通过 Nginx 反代访问后端,API 地址可能需要调整 | 新增一个 `.env.docker` 文件 | | **nginx.conf 反代路径** | 当前前端直接调用后端接口(无 `/api` 前缀),需确认 Nginx `location /api/` 的 rewrite 规则与前端请求路径一致 | `deploy/docker/conf/nginx.conf` | | **application-docker.yml 补全** | 当前只覆盖了数据源和 Redis,如果后端有其他外部依赖(如 OSS、短信等),需补充配置或 mock | `deploy/docker/conf/application-docker.yml` | --- ## 方案一:远程服务器部署(无 Docker) > 本地构建 → SCP 上传 → 远程重启 → 健康检查 → 失败自动回滚 → 飞书通知 ### 前置条件 1. 本机已安装 Java 8、Maven、Node.js 16+ 2. SSH 免密登录到目标服务器 ```bash # 配置 SSH 免密(一次性) ssh-keygen -t ed25519 ssh-copy-id root@192.168.1.182 # 验证 ssh root@192.168.1.182 "echo ok" ``` ### 首次使用 ```bash # 1. 根据实际环境修改配置 vi deploy/remote/config.sh # 2. 初始化服务器目录结构 + 上传管理脚本 deploy/remote/deploy.sh setup ``` ### 日常使用 ```bash # ===== 部署 ===== # 全量部署(前端 + 后端全部) deploy/remote/deploy.sh # 只改了后端 Web 代码 deploy/remote/deploy.sh web # 只改了 Task 服务代码 deploy/remote/deploy.sh task # 后端都改了 deploy/remote/deploy.sh backend # 只改了前端(生产包) deploy/remote/deploy.sh front # 前端测试环境包 deploy/remote/deploy.sh front-test # ===== 回滚 ===== # 回滚到上一版本 deploy/remote/deploy.sh rollback # 或 deploy/remote/rollback.sh # ===== 状态查看 ===== # 查看服务器服务状态 deploy/remote/deploy.sh status ``` ### 配置说明 编辑 `deploy/remote/config.sh`: ```bash # 服务器地址(根据实际修改) DEPLOY_HOST="192.168.1.182" DEPLOY_USER="root" # Tomcat 路径(根据服务器实际路径修改) TOMCAT_HOME="/opt/smartclean/web/tomcat" # 备份保留数量 MAX_BACKUPS=5 # 健康检查重试次数和间隔 HEALTHCHECK_RETRIES=20 HEALTHCHECK_INTERVAL=5 ``` ### 部署流程 ``` 1. 本地构建 → 调用 build.sh 生成 ROOT.war / task.jar / dist/ 2. 远程备份 → SSH 备份服务器当前版本到 backups/时间戳-hash/ 3. 上传产物 → SCP 传输到服务器对应目录 4. 远程重启 → SSH 执行 restart-web.sh / restart-task.sh / restart-front.sh 5. 健康检查 → 轮询接口,最多重试 20 次(每次间隔 5s) 6. 结果通知 → 成功/失败/回滚 均推送飞书群 ``` ### 服务器目录结构 ``` /opt/smartclean/ ├── web/tomcat/webapps/ROOT.war # Web 服务 ├── task/task.jar # Task 服务 ├── front/dist/ # 前端静态文件 ├── backups/ # 版本备份(自动保留最近 5 个) │ ├── 20260415-153000-a1b2c3d/ │ └── 20260415-140000-d4e5f6a/ └── scripts/ # 服务管理脚本 ├── restart-web.sh ├── restart-task.sh └── restart-front.sh ``` --- ## 方案二:Docker 本机模拟 > Docker 镜像构建 → Compose 部署 → 健康检查 → 失败自动回滚 → 飞书通知 ### 前置条件 1. 已安装 Docker Desktop 并启动 ```bash # 验证 docker --version docker compose version ``` ### 首次使用 ```bash # 直接一键部署(首次会自动拉取基础镜像 + 构建 + 启动) deploy/docker/deploy.sh ``` ### 日常使用 ```bash # ===== 部署 ===== # 全量部署 deploy/docker/deploy.sh # 只改了后端 Web 代码 deploy/docker/deploy.sh web # 只改了 Task 服务代码 deploy/docker/deploy.sh task # 只改了前端 deploy/docker/deploy.sh front # ===== 回滚 ===== # 回滚到上一版本(基于镜像 tag) deploy/docker/deploy.sh rollback # 或 deploy/docker/rollback.sh # ===== 运维 ===== # 查看容器状态 deploy/docker/deploy.sh status # 查看所有服务日志 deploy/docker/deploy.sh logs # 只看 Web 服务日志 deploy/docker/deploy.sh logs web # 停止所有容器(数据保留) deploy/docker/deploy.sh stop # 停止并清理数据卷(慎用,会丢数据库数据) deploy/docker/deploy.sh clean ``` ### 端口映射 | 服务 | 容器内端口 | 宿主机端口 | 访问地址 | |------|-----------|-----------|---------| | 前端 (Nginx) | 80 | **8180** | http://localhost:8180 | | Web 后端 | 8095 | **18095** | http://localhost:18095 | | Task 后端 | 8097 | **18097** | http://localhost:18097 | | MySQL | 3306 | **3307** | localhost:3307 | | Redis | 6379 | **6380** | localhost:6380 | > 端口可在 `deploy/docker/.env` 中自定义修改。 ### 端口隔离说明 Docker 环境与本机开发环境完全独立: ``` 本机开发环境 Docker 模拟环境 ────────────── ────────────── 前端 localhost:8079 前端 localhost:8180 Web localhost:8095 Web localhost:18095 MySQL localhost:3306 MySQL localhost:3307 Redis localhost:6379 Redis localhost:6380 ``` 两套可以同时运行,互不干扰。 ### 连接 Docker 中的数据库调试 ```bash # 用本机 MySQL 客户端连接 Docker 中的 MySQL mysql -h127.0.0.1 -P3307 -uroot -pkaixinjiuhao # 用本机 Redis 客户端连接 Docker 中的 Redis redis-cli -h 127.0.0.1 -p 6380 -a kaixinjiuhao ``` --- ## 两套方案对比 | 维度 | 远程服务器部署 | Docker 本机模拟 | |------|--------------|----------------| | **部署目标** | 192.168.1.182 远程服务器 | 本机 Docker 容器 | | **依赖** | SSH 免密登录 | Docker Desktop | | **构建方式** | 本机 mvn/npm 构建,上传产物 | Docker 多阶段构建(镜像内编译) | | **部署速度** | 快(只传几十 MB 产物) | 慢(首次构建镜像,后续有缓存) | | **环境一致性** | 依赖服务器已有环境 | 镜像自包含,完全一致 | | **回滚方式** | 文件级(还原备份的 WAR/JAR/dist) | 镜像级(切换 Docker 镜像 tag) | | **数据库** | 使用服务器上的 MySQL | 独立 MySQL 容器(数据隔离) | | **适合场景** | 日常发布到测试/生产 | 本机验证部署流程、新人搭环境 | ## 命令速查表 ```bash # ==================== 远程部署 ==================== deploy/remote/deploy.sh # 全量部署到远程服务器 deploy/remote/deploy.sh web # 只部署 Web deploy/remote/deploy.sh task # 只部署 Task deploy/remote/deploy.sh front # 只部署前端 deploy/remote/deploy.sh backend # 部署后端(web + task) deploy/remote/deploy.sh rollback # 回滚 deploy/remote/deploy.sh status # 查看服务器状态 deploy/remote/deploy.sh setup # 首次初始化服务器 # ==================== Docker 部署 ==================== deploy/docker/deploy.sh # 全量部署到 Docker deploy/docker/deploy.sh web # 只部署 Web deploy/docker/deploy.sh task # 只部署 Task deploy/docker/deploy.sh front # 只部署前端 deploy/docker/deploy.sh rollback # 回滚 deploy/docker/deploy.sh status # 查看容器状态 deploy/docker/deploy.sh logs [服务] # 查看日志 deploy/docker/deploy.sh stop # 停止容器 deploy/docker/deploy.sh clean # 停止并清理数据 ``` ## 飞书通知 两套方案都集成了飞书 Webhook 通知,部署结果会自动推送到群里: - ✅ **部署成功**:版本号、分支、提交信息、耗时 - ❌ **部署失败**:自动回滚后通知,附失败原因 - ⚠️ **手动回滚**:回滚版本号、操作人 Webhook 地址在各自的配置文件中修改: - 远程版:`deploy/remote/config.sh` → `FEISHU_WEBHOOK` - Docker 版:`deploy/docker/.env` → `FEISHU_WEBHOOK` ## 注意事项 1. **deploy/docker/.env 不要提交到 git**(含密码),已在 .gitignore 中排除 2. **首次 Docker 构建较慢**(需下载基础镜像 + Maven 依赖),后续有缓存会快很多 3. **远程部署前确认 config.sh 中的路径**与服务器实际一致,特别是 `TOMCAT_HOME` 4. **回滚只保留最近 5 个版本**,超出自动清理(可在配置中调整 `MAX_BACKUPS`) 5. **Docker 版 Task 服务**可能因缺少 MQTT/XXL-Job 而启动异常,这是正常的,不影响 Web 和前端