#!/usr/bin/env bash # 蝶雅智能体平台 — 生产环境一键升级脚本 # # 功能:将旧电脑(开发环境)的代码增量同步到新电脑(生产环境) # 自动迁移数据库结构,并重启 Gunicorn 服务 # 用法:bash upgrade_prod.sh set -euo pipefail # ========== 配置区(按实际修改) ========== REMOTE_IP="192.168.11.79" # 生产服务器 IP REMOTE_USER="dieya" # 生产服务器 SSH 用户名 REMOTE_DIR="/home/dieya/.openclaw/workspace/dy-dashboard" # 生产服务器项目路径 LOCAL_DIR="/home/gxd/.openclaw/workspace/dy-dashboard" # 本机项目路径 # ========================================== RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${CYAN}[INFO]${NC} $*"; } ok() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } err() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } echo "" echo -e "${GREEN}==========================================${NC}" echo -e "${GREEN} 蝶雅智能体平台 → 生产环境升级${NC}" echo -e "${GREEN}==========================================${NC}" echo "" info "本地路径:${LOCAL_DIR}" info "目标:${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}" echo "" # 1. 测试 SSH 连接 info "[1/5] 测试 SSH 连接..." if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new \ "${REMOTE_USER}@${REMOTE_IP}" "echo SSH_OK" 2>/dev/null | grep -q "SSH_OK"; then ok "SSH 连接成功" else err "SSH 连接失败,请检查\n ssh ${REMOTE_USER}@${REMOTE_IP}" fi # 2. 同步代码(rsync 仅传输变更的文件) info "[2/5] 同步代码..." rsync -avz --delete \ --exclude='venv/' \ --exclude='.git/' \ --exclude='__pycache__/' \ --exclude='*.pyc' \ --exclude='logs/' \ --exclude='backups/' \ --exclude='static/uploads/feedback/' \ --exclude='static/uploads/new_products/' \ --exclude='*.tar.gz' \ --exclude='*.sql' \ --exclude='routes/feedback.py' \ "${LOCAL_DIR}/" "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}/" ok "代码同步完成" # 新品图片保护:增量升级不让代码 rsync 删除生产图片,并在升级前单独备份。 TS=$(date +%Y%m%d_%H%M%S) ssh "${REMOTE_USER}@${REMOTE_IP}" " set -e mkdir -p ${REMOTE_DIR}_backups if [ -d ${REMOTE_DIR}/static/uploads/new_products ]; then tar -czf ${REMOTE_DIR}_backups/new_products_pre_upgrade_${TS}.tar.gz -C ${REMOTE_DIR}/static/uploads new_products fi " # 3. 数据库结构迁移(自动补全缺失的列/表) info "[3/5] 数据库结构迁移..." if ssh "${REMOTE_USER}@${REMOTE_IP}" \ "cd ${REMOTE_DIR} && venv/bin/python3 migrate_db.py 2>&1"; then ok "数据库结构检查通过,无需变更" else warn "数据库已自动补全新列(这是正常的)" fi # 4. 清理缓存 info "[4/5] 清理缓存..." ssh "${REMOTE_USER}@${REMOTE_IP}" " find ${REMOTE_DIR} -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null find ${REMOTE_DIR} -name '*.pyc' -delete 2>/dev/null rm -f /tmp/dy_* 2>/dev/null " || true ok "缓存清理完成" # 5. 重启 Gunicorn info "[5/5] 重启服务..." ssh "${REMOTE_USER}@${REMOTE_IP}" " # 停旧服务 PID=\$(lsof -t -i:18888 2>/dev/null) if [ -n \"\$PID\" ]; then kill -9 \$PID 2>/dev/null sleep 1 fi # 启动新服务 cd ${REMOTE_DIR} mkdir -p logs nohup venv/bin/gunicorn -w 4 -b 0.0.0.0:18888 --timeout 120 \ --access-logfile logs/access.log \ --error-logfile logs/error.log \ app:app > /dev/null 2>&1 & # 等待并验证 sleep 3 if curl -s http://127.0.0.1:18888/ > /dev/null 2>&1; then echo '__SUCCESS__' else echo '__FAILED__' fi " | grep -q "__SUCCESS__" && ok "服务重启成功" || \ warn "服务可能未启动,请检查:ssh ${REMOTE_USER}@${REMOTE_IP} 'tail -30 ${REMOTE_DIR}/logs/error.log'" echo "" echo -e "${GREEN}==========================================${NC}" echo -e "${GREEN} 升级完成!${NC}" echo -e "${GREEN}==========================================${NC}" echo "" echo -e " 访问地址:${CYAN}http://${REMOTE_IP}:18888${NC}" echo "" echo -e " ${YELLOW}如果升级后发现问题:${NC}" echo " 1. 查看错误日志:ssh ${REMOTE_USER}@${REMOTE_IP} 'tail -50 ${REMOTE_DIR}/logs/error.log'" echo " 2. 旧电脑代码不受影响,可继续本地调试" echo ""