#!/bin/bash # 考培练系统自动更新脚本 # 作者: AI Assistant # 日期: 2025-09-25 set -e # 配置变量 PROJECT_DIR="/root/aiedu" LOG_FILE="/var/log/kaopeilian_update.log" BACKUP_DIR="/root/aiedu/backups/updates" # 日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 创建备份目录 mkdir -p "$BACKUP_DIR" log "=== 开始检查代码更新 ===" cd "$PROJECT_DIR" # 获取当前提交哈希 LOCAL_COMMIT=$(git rev-parse HEAD) log "本地提交: $LOCAL_COMMIT" # 拉取最新代码 git fetch origin production # 获取远程提交哈希 REMOTE_COMMIT=$(git rev-parse origin/production) log "远程提交: $REMOTE_COMMIT" # 检查是否有更新 if [ "$LOCAL_COMMIT" = "$REMOTE_COMMIT" ]; then log "代码已是最新版本,无需更新" exit 0 fi log "发现代码更新,开始部署流程..." # 创建备份 BACKUP_NAME="backup_$(date '+%Y%m%d_%H%M%S')" log "创建备份: $BACKUP_NAME" # 备份当前代码 git stash push -m "Auto backup before update $BACKUP_NAME" # 备份数据库(如果MySQL容器在运行) if docker ps | grep -q kaopeilian-mysql; then docker exec kaopeilian-mysql mysqldump -u root -p'Kaopeilian2025!@#' kaopeilian > "$BACKUP_DIR/${BACKUP_NAME}_database.sql" log "数据库备份完成" fi # 拉取最新代码 log "拉取最新代码..." git pull origin production # 检查是否需要重新构建 NEED_REBUILD=false # 检查Docker文件变化 if git diff --name-only "$LOCAL_COMMIT" "$REMOTE_COMMIT" | grep -E "(Dockerfile|docker-compose\.yml|requirements\.txt|package\.json)"; then NEED_REBUILD=true log "检测到构建文件变化,需要重新构建镜像" fi # 检查前端文件变化并构建 if git diff --name-only "$LOCAL_COMMIT" "$REMOTE_COMMIT" | grep -E "kaopeilian-frontend/(src/|package\.json|vite\.config\.ts)"; then log "检测到前端代码变化,开始构建前端..." cd "$PROJECT_DIR/kaopeilian-frontend" # 确保依赖已安装 if [ ! -d "node_modules" ]; then log "安装前端依赖..." npm install fi # 构建前端 log "构建前端应用..." npm run build if [ $? -eq 0 ]; then log "前端构建成功" NEED_REBUILD=true else log "⚠️ 前端构建失败,但继续部署流程" fi cd "$PROJECT_DIR" fi # 停止服务 log "停止当前服务..." docker compose down # 重新构建(如果需要) if [ "$NEED_REBUILD" = true ]; then log "重新构建Docker镜像..." docker compose build --no-cache else log "使用现有镜像启动服务..." fi # 启动服务 log "启动更新后的服务..." docker compose up -d # 等待服务启动 sleep 60 # 健康检查 log "执行健康检查..." HEALTH_CHECK_URL="https://aiedu.ireborn.com.cn/health" # 尝试多次健康检查 RETRY_COUNT=0 MAX_RETRIES=5 while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do if curl -f -s -k "$HEALTH_CHECK_URL" > /dev/null; then log "✅ 健康检查通过,更新成功完成" # 清理旧的备份(保留最近5个) cd "$BACKUP_DIR" ls -t backup_*_database.sql 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true log "=== 自动更新完成 ===" exit 0 else RETRY_COUNT=$((RETRY_COUNT + 1)) log "健康检查失败,重试 $RETRY_COUNT/$MAX_RETRIES" sleep 10 fi done log "❌ 健康检查失败,开始回滚..." # 回滚代码 cd "$PROJECT_DIR" git reset --hard "$LOCAL_COMMIT" # 重新启动服务 docker compose down docker compose up -d log "回滚完成,请检查服务状态" exit 1