#!/bin/bash # 智队中枢自动更新脚本 # 当 Gitea 仓库有新提交时自动部署 set -e # 配置 LOG_FILE="/var/log/pit-router-update.log" REPO_DIR="/www/wwwroot/pit-router" BACKUP_DIR="/www/wwwroot/pit-router-backups" HEALTH_PORT=9000 HEALTH_RETRIES=10 HEALTH_INTERVAL=10 # 日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 创建备份 backup() { if [ -d "$REPO_DIR" ]; then mkdir -p "$BACKUP_DIR" BACKUP_NAME="pit-router-$(date '+%Y%m%d-%H%M%S').tar.gz" # 只备份关键配置,不备份 venv tar -czf "$BACKUP_DIR/$BACKUP_NAME" \ --exclude='venv' \ --exclude='__pycache__' \ --exclude='*.pyc' \ --exclude='.git' \ -C "$(dirname $REPO_DIR)" "$(basename $REPO_DIR)" 2>/dev/null || true log "备份创建: $BACKUP_NAME" # 只保留最近 3 个备份 cd "$BACKUP_DIR" ls -t | tail -n +4 | xargs rm -f 2>/dev/null || true cd "$REPO_DIR" fi } # 回滚函数 rollback() { log "⚠️ 开始回滚..." LATEST_BACKUP=$(ls -t "$BACKUP_DIR" | head -1) if [ -n "$LATEST_BACKUP" ]; then # 先停止当前容器 docker-compose down 2>/dev/null || true # 解压备份(只恢复配置文件) cd "$BACKUP_DIR" tar -xzf "$LATEST_BACKUP" -C "$(dirname $REPO_DIR)" --overwrite 2>/dev/null || true cd "$REPO_DIR" # 重新构建并启动 docker-compose build --no-cache 2>&1 | tail -3 docker-compose up -d log "✅ 回滚完成" else log "❌ 没有可用的备份" fi } # 健康检查 health_check() { local count=0 while [ $count -lt $HEALTH_RETRIES ]; do if curl -sf http://localhost:$HEALTH_PORT/health > /dev/null 2>&1; then return 0 fi count=$((count + 1)) log "健康检查重试 $count/$HEALTH_RETRIES..." sleep $HEALTH_INTERVAL done return 1 } # 主流程 main() { log "========== 🚀 开始自动更新 ==========" cd "$REPO_DIR" || exit 1 # 1. 创建备份 log "📦 创建备份..." backup # 2. 拉取最新代码 log "📥 拉取最新代码..." git fetch origin git reset --hard origin/main # 记录当前 commit COMMIT=$(git rev-parse --short HEAD) log "当前版本: $COMMIT" # 3. 停止旧容器 log "🛑 停止旧容器..." docker-compose down 2>/dev/null || true # 4. 构建新镜像 log "🔨 构建新镜像..." docker-compose build --no-cache 2>&1 | tail -5 # 5. 启动新容器 log "🚀 启动新容器..." docker-compose up -d # 6. 等待服务启动 log "⏳ 等待服务启动..." sleep 30 # 7. 健康检查 log "🏥 健康检查..." if health_check; then log "✅ 更新成功!服务运行正常" log "========== 🎉 更新完成 ==========" exit 0 else log "❌ 健康检查失败!" rollback log "========== ⚠️ 更新失败,已回滚 ==========" exit 1 fi } # 执行 main "$@"