- 新增 deploy/docker/:Docker 本机模拟部署,含 Dockerfile、docker-compose、deploy.sh 一键脚本 - 新增 deploy/remote/:远程服务器部署,含 SSH 自动上传、重启、回滚脚本 - 新增 deploy/README.md:完整使用手册,含现状分析、落地调整工作清单、命令速查 - 新增 build.sh/start.sh:本地构建和启动脚本(含飞书通知) - 新增前端 .env.docker 环境配置,API 指向测试服务器 - 前端 package.json 新增 build-docker 命令 - 更新 .gitignore:排除 IDE 配置、SQL 数据、Docker 敏感文件 - 前端 UI 样式优化(多个页面组件) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
23 KiB
23 KiB
SmartClean 自动化打包部署方案(无 Docker 版)
一、目标
基于现有 build.sh 构建能力,实现 一键构建 → 远程备份 → 上传部署 → 服务重启 → 健康检查 → 失败回滚 → 飞书通知 全流程自动化。不依赖 Docker,直接操作远程服务器。
二、前提条件
| 条件 | 说明 |
|---|---|
| SSH 免密登录 | 本机 → 182 服务器配好 SSH Key,免输密码 |
| 服务器目录约定 | 统一部署路径,脚本按约定操作 |
| 现有构建脚本 | 复用已有的 build.sh |
SSH 免密配置(一次性)
# 生成密钥(如已有可跳过)
ssh-keygen -t ed25519
# 将公钥复制到服务器
ssh-copy-id root@192.168.1.182
# 验证
ssh root@192.168.1.182 "echo ok"
三、整体架构
本机 (Mac) 远程服务器 (192.168.1.182)
┌──────────────────────┐ ┌──────────────────────────────┐
│ │ │ │
│ 源码 → build.sh 构建 │ │ /opt/smartclean/ │
│ │ SCP 上传 │ ├── web/ │
│ 产物: │ ──────────────→ │ │ └── ROOT.war │
│ - ROOT.war │ │ ├── task/ │
│ - task.jar │ SSH 远程执行 │ │ └── task.jar │
│ - dist/ │ ──────────────→ │ ├── front/ │
│ │ │ │ └── dist/ │
│ deploy.sh 控制全流程 │ │ ├── backups/ │
│ │ │ │ ├── 20260415-153000/ │
│ │ │ │ └── 20260415-140000/ │
│ │ │ └── scripts/ │
│ │ │ ├── restart-web.sh │
│ │ │ ├── restart-task.sh │
│ │ │ └── restart-front.sh │
└──────────────────────┘ └──────────────────────────────┘
四、服务器目录规划
/opt/smartclean/ # 部署根目录
├── web/
│ ├── tomcat/ # Tomcat 安装目录
│ │ └── webapps/
│ │ └── ROOT.war # Web 服务 WAR 包
│ └── logs/
├── task/
│ ├── task.jar # Task 服务 JAR 包
│ ├── task.pid # 进程 PID 文件
│ └── logs/
├── front/
│ └── dist/ # 前端静态文件(Nginx 指向此目录)
├── backups/ # 版本备份(自动保留最近 5 个)
│ ├── 20260415-153000/
│ │ ├── ROOT.war
│ │ ├── task.jar
│ │ └── dist/
│ └── 20260415-140000/
│ └── ...
└── scripts/ # 服务器端管理脚本
├── restart-web.sh
├── restart-task.sh
└── restart-front.sh
五、新增文件结构
smartclean/
├── build.sh # 已有,构建脚本
└── deploy/
├── deploy.sh # 一键部署主脚本(本机执行)
├── rollback.sh # 一键回滚脚本(本机执行)
├── config.sh # 部署配置(服务器地址、路径等)
├── .env # 敏感信息(密码等,不入 git)
└── remote/ # 服务器端脚本(首次部署时自动上传)
├── setup.sh # 服务器初始化(创建目录结构,一次性)
├── restart-web.sh # 重启 Web 服务(Tomcat)
├── restart-task.sh # 重启 Task 服务(JAR)
└── restart-front.sh # 重新加载前端(Nginx reload)
六、配置文件
6.1 部署配置
# deploy/config.sh
# ===== 服务器配置 =====
DEPLOY_HOST="192.168.1.182"
DEPLOY_USER="root"
DEPLOY_BASE="/opt/smartclean"
# ===== 服务器目录 =====
REMOTE_WEB_DIR="$DEPLOY_BASE/web"
REMOTE_TASK_DIR="$DEPLOY_BASE/task"
REMOTE_FRONT_DIR="$DEPLOY_BASE/front"
REMOTE_BACKUP_DIR="$DEPLOY_BASE/backups"
REMOTE_SCRIPTS_DIR="$DEPLOY_BASE/scripts"
# ===== Tomcat 配置 =====
TOMCAT_HOME="/opt/smartclean/web/tomcat"
TOMCAT_WEBAPPS="$TOMCAT_HOME/webapps"
# ===== Nginx 配置 =====
NGINX_HTML="/opt/smartclean/front/dist"
# ===== Task 服务配置 =====
TASK_JAR_NAME="xiaoqu-intellectual-task-0.0.1-SNAPSHOT.jar"
TASK_PROFILE="prod"
TASK_JVM_OPTS="-Xms256m -Xmx512m"
# ===== 本地构建产物路径 =====
LOCAL_WAR="backend/xiaoqu-intellectual-web/target/ROOT.war"
LOCAL_TASK_JAR="backend/xiaoqu-intellectual-task/target/$TASK_JAR_NAME"
LOCAL_FRONT_DIST="frontend/witcleansystem/dist"
# ===== 备份保留数量 =====
MAX_BACKUPS=5
# ===== 健康检查 =====
HEALTHCHECK_URL="http://$DEPLOY_HOST:8095/dropDown/districtTree"
HEALTHCHECK_RETRIES=20
HEALTHCHECK_INTERVAL=5
# ===== 飞书通知 =====
FEISHU_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/5703e8cc-6998-46a6-af9d-8c5102cc8c1e"
七、服务器端脚本
7.1 服务器初始化脚本(一次性执行)
# deploy/remote/setup.sh
#!/bin/bash
# 在服务器上创建标准目录结构,仅需执行一次
DEPLOY_BASE="/opt/smartclean"
mkdir -p "$DEPLOY_BASE"/{web/logs,task/logs,front,backups,scripts}
echo "目录结构创建完成:"
find "$DEPLOY_BASE" -maxdepth 2 -type d
7.2 重启 Web 服务
# deploy/remote/restart-web.sh
#!/bin/bash
# 重启 Tomcat(部署 ROOT.war)
TOMCAT_HOME="/opt/smartclean/web/tomcat"
echo "[INFO] 停止 Tomcat..."
"$TOMCAT_HOME/bin/shutdown.sh" 2>/dev/null
sleep 3
# 确保进程已停
TOMCAT_PID=$(ps -ef | grep "catalina" | grep -v grep | awk '{print $2}')
if [ -n "$TOMCAT_PID" ]; then
echo "[WARN] Tomcat 未正常关闭,强制终止 PID=$TOMCAT_PID"
kill -9 $TOMCAT_PID
sleep 1
fi
# 清理旧的解压目录,保留 WAR
rm -rf "$TOMCAT_HOME/webapps/ROOT"
rm -rf "$TOMCAT_HOME/work/Catalina"
echo "[INFO] 启动 Tomcat..."
"$TOMCAT_HOME/bin/startup.sh"
echo "[INFO] Tomcat 已启动"
7.3 重启 Task 服务
# deploy/remote/restart-task.sh
#!/bin/bash
# 重启 Task 服务(Spring Boot JAR)
TASK_DIR="/opt/smartclean/task"
JAR_FILE="$TASK_DIR/task.jar"
PID_FILE="$TASK_DIR/task.pid"
LOG_FILE="$TASK_DIR/logs/task.log"
PROFILE="${1:-prod}"
JVM_OPTS="${2:--Xms256m -Xmx512m}"
# 停止旧进程
if [ -f "$PID_FILE" ]; then
OLD_PID=$(cat "$PID_FILE")
if kill -0 "$OLD_PID" 2>/dev/null; then
echo "[INFO] 停止旧进程 PID=$OLD_PID"
kill "$OLD_PID"
sleep 3
# 强制终止
if kill -0 "$OLD_PID" 2>/dev/null; then
kill -9 "$OLD_PID"
fi
fi
rm -f "$PID_FILE"
fi
# 启动新进程
echo "[INFO] 启动 Task 服务 (profile=$PROFILE)..."
nohup java $JVM_OPTS \
-jar "$JAR_FILE" \
--spring.profiles.active=$PROFILE \
> "$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
echo "[INFO] Task 服务已启动, PID=$(cat "$PID_FILE")"
7.4 重新加载前端
# deploy/remote/restart-front.sh
#!/bin/bash
# 重新加载 Nginx(前端静态文件已更新)
echo "[INFO] 测试 Nginx 配置..."
nginx -t 2>&1
if [ $? -ne 0 ]; then
echo "[ERROR] Nginx 配置有误"
exit 1
fi
echo "[INFO] 重新加载 Nginx..."
nginx -s reload
echo "[INFO] Nginx 已重新加载"
八、一键部署主脚本
# deploy/deploy.sh
#!/bin/bash
#
# SmartClean 一键部署脚本(无 Docker 版)
#
# 用法:
# ./deploy.sh # 构建并部署所有服务
# ./deploy.sh web # 仅构建部署 Web 服务
# ./deploy.sh task # 仅构建部署 Task 服务
# ./deploy.sh front # 仅构建部署前端
# ./deploy.sh front-test # 构建测试环境前端并部署
# ./deploy.sh backend # 构建部署后端(web + task)
# ./deploy.sh rollback # 回滚到上一版本
# ./deploy.sh setup # 首次初始化服务器目录
set -e
DEPLOY_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(dirname "$DEPLOY_DIR")"
source "$DEPLOY_DIR/config.sh"
# ===== 版本号 =====
GIT_HASH=$(cd "$ROOT_DIR" && git rev-parse --short HEAD)
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
VERSION="${TIMESTAMP}-${GIT_HASH}"
BRANCH=$(cd "$ROOT_DIR" && git rev-parse --abbrev-ref HEAD)
COMMIT=$(cd "$ROOT_DIR" && git log -1 --format='%h %s')
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
SSH_CMD="ssh $DEPLOY_USER@$DEPLOY_HOST"
SCP_CMD="scp"
# ===== 飞书通知 =====
notify_feishu() {
local title="$1" content="$2" color="$3"
curl -s -X POST "$FEISHU_WEBHOOK" \
-H "Content-Type: application/json" \
-d "{
\"msg_type\": \"interactive\",
\"card\": {
\"header\": {\"title\":{\"tag\":\"plain_text\",\"content\":\"$title\"},\"template\":\"$color\"},
\"elements\": [{\"tag\":\"markdown\",\"content\":\"$content\"}]
}
}" > /dev/null 2>&1
}
# ===== 检查 SSH 连接 =====
check_ssh() {
log_info "检查 SSH 连接..."
if ! $SSH_CMD "echo ok" > /dev/null 2>&1; then
log_error "无法连接到 $DEPLOY_USER@$DEPLOY_HOST"
log_error "请先配置 SSH 免密登录: ssh-copy-id $DEPLOY_USER@$DEPLOY_HOST"
exit 1
fi
log_info "SSH 连接正常"
}
# ===== 首次初始化服务器 =====
setup_server() {
log_info "初始化服务器目录结构..."
$SCP_CMD "$DEPLOY_DIR/remote/setup.sh" "$DEPLOY_USER@$DEPLOY_HOST:/tmp/setup.sh"
$SSH_CMD "bash /tmp/setup.sh"
log_info "上传服务器端管理脚本..."
$SCP_CMD "$DEPLOY_DIR/remote/restart-web.sh" "$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_SCRIPTS_DIR/"
$SCP_CMD "$DEPLOY_DIR/remote/restart-task.sh" "$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_SCRIPTS_DIR/"
$SCP_CMD "$DEPLOY_DIR/remote/restart-front.sh" "$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_SCRIPTS_DIR/"
$SSH_CMD "chmod +x $REMOTE_SCRIPTS_DIR/*.sh"
log_info "服务器初始化完成"
}
# ===== 本地构建 =====
build_local() {
local target="$1"
log_info "开始本地构建 (目标: $target)..."
cd "$ROOT_DIR"
bash build.sh "$target"
# 验证产物存在
case "$target" in
web|backend|all)
if [ ! -f "$ROOT_DIR/$LOCAL_WAR" ]; then
log_error "构建产物不存在: $LOCAL_WAR"
exit 1
fi
;;
esac
case "$target" in
task|backend|all)
if [ ! -f "$ROOT_DIR/$LOCAL_TASK_JAR" ]; then
log_error "构建产物不存在: $LOCAL_TASK_JAR"
exit 1
fi
;;
esac
case "$target" in
front|front-test|all)
if [ ! -d "$ROOT_DIR/$LOCAL_FRONT_DIST" ]; then
log_error "构建产物不存在: $LOCAL_FRONT_DIST"
exit 1
fi
;;
esac
log_info "本地构建完成"
}
# ===== 远程备份 =====
backup_remote() {
local target="$1"
log_info "备份服务器当前版本 ($VERSION)..."
$SSH_CMD bash <<EOF
BACKUP="$REMOTE_BACKUP_DIR/$VERSION"
mkdir -p "\$BACKUP"
# 按目标备份
case "$target" in
web|backend|all)
cp "$TOMCAT_WEBAPPS/ROOT.war" "\$BACKUP/" 2>/dev/null && echo "已备份 ROOT.war" || echo "ROOT.war 不存在,跳过"
;;
esac
case "$target" in
task|backend|all)
cp "$REMOTE_TASK_DIR/task.jar" "\$BACKUP/" 2>/dev/null && echo "已备份 task.jar" || echo "task.jar 不存在,跳过"
;;
esac
case "$target" in
front|front-test|all)
if [ -d "$REMOTE_FRONT_DIR/dist" ]; then
cp -r "$REMOTE_FRONT_DIR/dist" "\$BACKUP/"
echo "已备份 front/dist"
fi
;;
esac
# 清理过期备份,保留最近 $MAX_BACKUPS 个
cd "$REMOTE_BACKUP_DIR"
ls -dt */ 2>/dev/null | tail -n +\$(($MAX_BACKUPS + 1)) | xargs rm -rf 2>/dev/null
echo "当前备份列表:"
ls -dt */ 2>/dev/null | head -5
EOF
log_info "远程备份完成"
}
# ===== 上传产物 =====
upload_artifacts() {
local target="$1"
case "$target" in
web|backend|all)
log_info "上传 ROOT.war..."
$SCP_CMD "$ROOT_DIR/$LOCAL_WAR" "$DEPLOY_USER@$DEPLOY_HOST:$TOMCAT_WEBAPPS/ROOT.war"
;;
esac
case "$target" in
task|backend|all)
log_info "上传 task.jar..."
$SCP_CMD "$ROOT_DIR/$LOCAL_TASK_JAR" "$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_TASK_DIR/task.jar"
;;
esac
case "$target" in
front|front-test|all)
log_info "上传前端文件..."
# 先清空远程 dist,再上传
$SSH_CMD "rm -rf $REMOTE_FRONT_DIR/dist"
$SCP_CMD -r "$ROOT_DIR/$LOCAL_FRONT_DIST" "$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_FRONT_DIR/dist"
;;
esac
log_info "产物上传完成"
}
# ===== 远程重启服务 =====
restart_services() {
local target="$1"
case "$target" in
web|backend|all)
log_info "重启 Web 服务..."
$SSH_CMD "bash $REMOTE_SCRIPTS_DIR/restart-web.sh"
;;
esac
case "$target" in
task|backend|all)
log_info "重启 Task 服务..."
$SSH_CMD "bash $REMOTE_SCRIPTS_DIR/restart-task.sh $TASK_PROFILE '$TASK_JVM_OPTS'"
;;
esac
case "$target" in
front|front-test|all)
log_info "重新加载前端..."
$SSH_CMD "bash $REMOTE_SCRIPTS_DIR/restart-front.sh"
;;
esac
}
# ===== 健康检查 =====
healthcheck() {
local target="$1"
# Web 服务检查
if [ "$target" = "all" ] || [ "$target" = "web" ] || [ "$target" = "backend" ]; then
log_info "健康检查 Web 服务 ($HEALTHCHECK_URL)..."
for i in $(seq 1 $HEALTHCHECK_RETRIES); do
if curl -sf "$HEALTHCHECK_URL" > /dev/null 2>&1; then
log_info "✅ Web 服务健康 (第${i}次检查)"
return 0
fi
echo -n "."
sleep $HEALTHCHECK_INTERVAL
done
log_error "❌ Web 服务健康检查失败 (${HEALTHCHECK_RETRIES}次重试后)"
return 1
fi
# 前端检查
if [ "$target" = "front" ] || [ "$target" = "front-test" ]; then
log_info "健康检查前端..."
if curl -sf "http://$DEPLOY_HOST/" > /dev/null 2>&1; then
log_info "✅ 前端服务健康"
return 0
else
log_error "❌ 前端服务健康检查失败"
return 1
fi
fi
return 0
}
# ===== 回滚 =====
rollback() {
log_info "查找最近的备份..."
# 获取最近的备份目录名
LATEST_BACKUP=$($SSH_CMD "ls -dt $REMOTE_BACKUP_DIR/*/ 2>/dev/null | head -1 | xargs basename 2>/dev/null")
if [ -z "$LATEST_BACKUP" ]; then
log_error "没有可回滚的备份"
exit 1
fi
log_warn "回滚到版本: $LATEST_BACKUP"
$SSH_CMD bash <<EOF
BACKUP="$REMOTE_BACKUP_DIR/$LATEST_BACKUP"
# 还原 WAR
if [ -f "\$BACKUP/ROOT.war" ]; then
cp "\$BACKUP/ROOT.war" "$TOMCAT_WEBAPPS/ROOT.war"
echo "已还原 ROOT.war"
fi
# 还原 Task JAR
if [ -f "\$BACKUP/task.jar" ]; then
cp "\$BACKUP/task.jar" "$REMOTE_TASK_DIR/task.jar"
echo "已还原 task.jar"
fi
# 还原前端
if [ -d "\$BACKUP/dist" ]; then
rm -rf "$REMOTE_FRONT_DIR/dist"
cp -r "\$BACKUP/dist" "$REMOTE_FRONT_DIR/dist"
echo "已还原 front/dist"
fi
EOF
# 重启所有服务
restart_services "all"
log_info "回滚完成"
notify_feishu "⚠️ SmartClean 已回滚" \
"**回滚版本:** $LATEST_BACKUP\\n**服务器:** $DEPLOY_HOST\\n**操作人:** $(whoami)@$(hostname)" \
"yellow"
}
# ===== 主流程 =====
TARGET="${1:-all}"
DEPLOY_START=$(date +%s)
# 特殊命令
case "$TARGET" in
setup)
check_ssh
setup_server
exit 0
;;
rollback)
check_ssh
rollback
exit 0
;;
esac
log_info "======================================"
log_info " SmartClean 自动化部署"
log_info " 版本: $VERSION"
log_info " 分支: $BRANCH"
log_info " 目标: $TARGET"
log_info " 服务器: $DEPLOY_USER@$DEPLOY_HOST"
log_info "======================================"
# 1. 检查连接
check_ssh
# 2. 本地构建
build_local "$TARGET"
# 3. 远程备份当前版本
backup_remote "$TARGET"
# 4. 上传构建产物
upload_artifacts "$TARGET"
# 5. 远程重启服务
restart_services "$TARGET"
# 6. 健康检查
if healthcheck "$TARGET"; then
ELAPSED=$(( $(date +%s) - DEPLOY_START ))
log_info "======================================"
log_info " ✅ 部署成功!"
log_info " 版本: $VERSION"
log_info " 耗时: ${ELAPSED}s"
log_info " 前端: http://$DEPLOY_HOST"
log_info " Web: http://$DEPLOY_HOST:8095"
log_info " Task: http://$DEPLOY_HOST:8097"
log_info "======================================"
notify_feishu "✅ SmartClean 部署成功" \
"**版本:** $VERSION\\n**分支:** $BRANCH\\n**提交:** $COMMIT\\n**目标:** $TARGET\\n**服务器:** $DEPLOY_HOST\\n**耗时:** ${ELAPSED}s\\n**操作人:** $(whoami)@$(hostname)" \
"green"
else
log_error "健康检查失败,自动回滚..."
rollback
ELAPSED=$(( $(date +%s) - DEPLOY_START ))
notify_feishu "❌ SmartClean 部署失败(已回滚)" \
"**版本:** $VERSION\\n**分支:** $BRANCH\\n**提交:** $COMMIT\\n**服务器:** $DEPLOY_HOST\\n**耗时:** ${ELAPSED}s\\n**状态:** 健康检查失败,已自动回滚" \
"red"
exit 1
fi
九、回滚脚本
# deploy/rollback.sh
#!/bin/bash
# 快捷回滚入口
DEPLOY_DIR="$(cd "$(dirname "$0")" && pwd)"
exec "$DEPLOY_DIR/deploy.sh" rollback
十、使用方式
首次使用(一次性设置)
# 1. 配置 SSH 免密登录
ssh-copy-id root@192.168.1.182
# 2. 初始化服务器目录结构 + 上传管理脚本
./deploy/deploy.sh setup
# 3. 根据实际情况修改 deploy/config.sh 中的路径配置
# 特别是 TOMCAT_HOME 要对应服务器上实际的 Tomcat 安装路径
日常部署
# 全量部署(构建全部 + 部署全部)
./deploy/deploy.sh
# 只改了后端 Web 代码
./deploy/deploy.sh web
# 只改了 Task 服务代码
./deploy/deploy.sh task
# 后端都改了
./deploy/deploy.sh backend
# 只改了前端(生产包)
./deploy/deploy.sh front
# 前端测试环境包
./deploy/deploy.sh front-test
# 出问题了,一键回滚
./deploy/deploy.sh rollback
查看服务器上的备份
ssh root@192.168.1.182 "ls -lt /opt/smartclean/backups/"
十一、部署流程图(以 ./deploy.sh web 为例)
本机 192.168.1.182
──── ─────────────
1. mvn clean package
→ ROOT.war 生成
2. mkdir backups/20260415-153000/
cp ROOT.war → backups/
3. scp ROOT.war ───────────────→ 4. ROOT.war → tomcat/webapps/
5. shutdown.sh → rm ROOT/ → startup.sh
6. curl http://182:8095/health
├── ✅ 成功 → 飞书通知"部署成功"
└── ❌ 失败 → 触发回滚
7. (回滚) cp backups/最新/ROOT.war → webapps/
→ restart tomcat
飞书通知"已回滚" ←──────
十二、与 Docker 版方案对比
| 维度 | 本方案(无 Docker) | Docker 版 |
|---|---|---|
| 依赖 | 仅需 SSH + SCP | 需要 Docker |
| 环境一致性 | 依赖服务器已有环境(JDK、Tomcat、Nginx) | 镜像自包含,环境完全一致 |
| 部署速度 | 快(只传产物,几十 MB) | 慢(构建镜像,几百 MB) |
| 适合场景 | 服务器少(1-3 台),已有运行环境 | 多环境、多服务器、需要环境隔离 |
| 回滚 | 文件级回滚(还原备份文件) | 镜像级回滚(切换镜像 tag) |
| 学习成本 | 低(Shell + SSH) | 中(需了解 Docker) |
| 改造成本 | 低(复用现有 build.sh + 服务器环境) | 中(需编写 Dockerfile、调试容器配置) |
十三、后续演进
| 阶段 | 动作 |
|---|---|
| 当前 | 本方案:本机执行 deploy.sh,SSH 部署到 182 |
| 阶段 2 | 多环境:config.sh 支持 --env test/prod 参数,切换不同服务器 |
| 阶段 3 | CI/CD:将 deploy.sh 逻辑搬到 Gitea Actions,push 自动触发 |
| 阶段 4 | 按需容器化:逐步将服务迁入 Docker,deploy.sh 改为推送镜像 |
十四、安全注意事项
- deploy/.env 不入 git:在
.gitignore中添加deploy/.env - SSH Key 管理:建议为部署专用创建独立 Key,限制只能执行特定命令
- 备份清理:默认保留最近 5 个备份,可在 config.sh 中调整
MAX_BACKUPS - 操作审计:每次部署的版本号、操作人、时间都会通过飞书通知记录