dy-dashboard/migrate_to_prod.sh
2026-10-28 11:14:17 +08:00

315 lines
11 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# ================================================================
# 蝶雅智能体平台 - 一键迁移到生产服务器
# ================================================================
set -euo pipefail
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; }
# ================================================================
DB_USER="dy_app"
DB_PASS="dy_data_2026"
DB_NAME="dy_data"
APP_PORT=18888
# ================================================================
clear
echo -e "${CYAN}============================================${NC}"
echo -e "${CYAN} 蝶雅智能体平台 → 生产服务器一键迁移${NC}"
echo -e "${CYAN}============================================${NC}"
echo ""
read -rp "请输入新电脑 IP 地址: " REMOTE_IP
read -rp "请输入新电脑 SSH 用户名(默认 gxd): " REMOTE_USER
REMOTE_USER="${REMOTE_USER:-gxd}"
# 自动获取新电脑的家目录
REMOTE_HOME=$(ssh -o ConnectTimeout=5 "${REMOTE_USER}@${REMOTE_IP}" "echo \$HOME" 2>/dev/null)
if [ -z "${REMOTE_HOME}" ]; then
err "无法获取远程家目录,请检查 SSH 连接"
fi
REMOTE_DIR="${REMOTE_HOME}/.openclaw/workspace/dy-dashboard"
echo ""
info "新电脑用户:${REMOTE_USER}"
info "家目录:${REMOTE_HOME}"
info "项目路径:${REMOTE_DIR}"
echo ""
# ================================================================
# 1. 测试 SSH 连接
# ================================================================
info "1/9 测试 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 连接失败,请检查。提示:先执行 ssh-copy-id ${REMOTE_USER}@${REMOTE_IP}"
fi
# ================================================================
# 2. 配置免密码 sudo
# ================================================================
info "2/9 配置新电脑免密码 sudo..."
echo ""
echo -e "${YELLOW}→ 接下来需要输入新电脑的 sudo 密码(输入时不会显示字符),输完回车即可${NC}"
echo ""
ssh -tt "${REMOTE_USER}@${REMOTE_IP}" "
CURRENT_USER=$(whoami)
if [ -f \"/etc/sudoers.d/\${CURRENT_USER}\" ]; then
echo ' [新电脑] 免密码 sudo 已配置,跳过'
else
echo '\${CURRENT_USER} ALL=(ALL) NOPASSWD:***' | sudo tee /etc/sudoers.d/\${CURRENT_USER} > /dev/null
sudo chmod 440 /etc/sudoers.d/\${CURRENT_USER}
echo ' [新电脑] ✅ 免密码 sudo 配置完成'
fi
" || {
err "免密码 sudo 配置失败,请手动执行:\n ssh ${REMOTE_USER}@${REMOTE_IP}\n sudo tee /etc/sudoers.d/${REMOTE_USER} <<< \"${REMOTE_USER} ALL=(ALL) NOPASSWD:***\"\n sudo chmod 440 /etc/sudoers.d/${REMOTE_USER}\n然后重新运行脚本"
}
ok "免密码 sudo 配置完成"
# ================================================================
# 3. 检查本机数据库
# ================================================================
info "3/9 检查本机 MySQL..."
if command -v mysql &>/dev/null; then
if mysql -u"${DB_USER}" -p"${DB_PASS}" -e "USE ${DB_NAME}; SELECT COUNT(*) AS tables FROM information_schema.tables WHERE table_schema='${DB_NAME}';" 2>/dev/null; then
ok "本机数据库就绪"
else
warn "MySQL 能连但数据可能不全,将尝试导出..."
fi
else
warn "本机无 mysql 命令,尝试用 mysqldump 直接导出..."
fi
# ================================================================
# 4. 导出数据库
# ================================================================
SQL_DUMP="/tmp/dy_data_migration_$(date +%Y%m%d_%H%M%S).sql"
info "4/9 导出本机数据库 → ${SQL_DUMP}..."
if mysqldump \
-h 127.0.0.1 \
-u "${DB_USER}" \
-p"${DB_PASS}" \
--single-transaction \
--no-tablespaces \
--routines \
--triggers \
--default-character-set=utf8mb4 \
"${DB_NAME}" > "${SQL_DUMP}" 2>/dev/null; then
SQL_SIZE=$(du -h "${SQL_DUMP}" | cut -f1)
ok "数据库导出完成 (${SQL_SIZE})"
else
rm -f "${SQL_DUMP}"
err "数据库导出失败,请检查 MySQL 是否在运行"
fi
# ================================================================
# 5. 传输 SQL 到新电脑
# ================================================================
info "5/9 传输 SQL 到新电脑..."
scp "${SQL_DUMP}" "${REMOTE_USER}@${REMOTE_IP}:/tmp/dy_data_import.sql"
ok "SQL 文件传输完成"
# ================================================================
# 6. 新电脑安装 MySQL + 建库 + 导数据
# ================================================================
info "6/9 在新电脑上安装 MySQL + 导数据..."
ssh "${REMOTE_USER}@${REMOTE_IP}" bash -s << 'REMOTE_SETUP'
#!/usr/bin/env bash
DB_USER="dy_app"
DB_PASS="dy_data_2026"
DB_NAME="dy_data"
echo " [新电脑] 检查 MySQL..."
if ! command -v mysql &>/dev/null; then
echo " [新电脑] 安装 MySQL..."
sudo apt update -qq
sudo DEBIAN_FRONTEND=noninteractive apt install -y -qq mysql-server
echo " [新电脑] MySQL 安装完成"
else
echo " [新电脑] MySQL 已安装:$(mysql --version)"
fi
echo " [新电脑] 启动 MySQL..."
sudo systemctl enable mysql 2>/dev/null || true
sudo systemctl start mysql 2>/dev/null || true
for i in $(seq 1 30); do
if sudo mysql -e "SELECT 1" &>/dev/null; then break; fi
sleep 1
done
echo " [新电脑] 创建数据库和用户..."
sudo mysql -e "
CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
ALTER USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
FLUSH PRIVILEGES;
"
echo " [新电脑] 导入数据(请耐心等待)..."
mysql -u"${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" < /tmp/dy_data_import.sql
TABLE_COUNT=$(mysql -u"${DB_USER}" -p"${DB_PASS}" -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}';" 2>/dev/null)
echo " [新电脑] 数据导入完成,共 ${TABLE_COUNT} 张表"
rm -f /tmp/dy_data_import.sql
REMOTE_SETUP
ok "新电脑数据库部署完成"
# ================================================================
# 7. 新电脑部署数据平台
# ================================================================
info "7/9 在新电脑上部署数据平台..."
# 构建远程脚本,传入正确的目录
ssh "${REMOTE_USER}@${REMOTE_IP}" bash -s "${REMOTE_DIR}" << 'REMOTE_DEPLOY'
#!/usr/bin/env bash
REMOTE_DIR="$1"
echo " [新电脑] 检查目录:${REMOTE_DIR}"
if [ ! -d "${REMOTE_DIR}" ]; then
echo " [新电脑] 错误:项目目录不存在!"
echo " [新电脑] 期望路径:${REMOTE_DIR}"
exit 1
fi
cd "${REMOTE_DIR}"
echo " [新电脑] 项目目录已找到"
# Python3
if ! command -v python3 &>/dev/null; then
echo " [新电脑] 安装 Python3..."
sudo apt install -y -qq python3 python3-pip python3-venv
fi
# 虚拟环境
if [ ! -d "${REMOTE_DIR}/venv" ]; then
echo " [新电脑] 创建 Python 虚拟环境..."
python3 -m venv "${REMOTE_DIR}/venv"
fi
# 依赖
echo " [新电脑] 安装 Python 依赖..."
source "${REMOTE_DIR}/venv/bin/activate"
pip install --quiet --upgrade pip
pip install --quiet \
flask==3.1.3 \
pymysql==1.2.0 \
gunicorn==26.0.0 \
gevent==26.5.0 \
openpyxl==3.1.5 \
DBUtils==3.1.2 \
flask-cors==6.0.2 \
Flask-Login==0.6.3 \
Flask-Compress==1.24
deactivate
mkdir -p "${REMOTE_DIR}/logs"
# 停旧服务
echo " [新电脑] 停止旧服务..."
kill "$(lsof -t -i:18888)" 2>/dev/null || true
sleep 1
# 启动
echo " [新电脑] 启动 Gunicorn(端口 18888)..."
nohup "${REMOTE_DIR}/venv/bin/gunicorn" \
-w 4 \
-b 0.0.0.0:18888 \
--timeout 120 \
--access-logfile "${REMOTE_DIR}/logs/access.log" \
--error-logfile "${REMOTE_DIR}/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 " [新电脑] ✅ 数据平台服务启动成功!"
else
echo " [新电脑] ⚠️ 服务可能尚未启动,稍后请手动检查:curl http://127.0.0.1:18888"
fi
REMOTE_DEPLOY
ok "新电脑数据平台部署完成"
# ================================================================
# 8. 新电脑配置定时任务
# ================================================================
info "8/9 在新电脑上配置定时任务..."
ssh "${REMOTE_USER}@${REMOTE_IP}" bash -s "${REMOTE_DIR}" << 'REMOTE_CRON'
#!/usr/bin/env bash
REMOTE_DIR="$1"
echo " [新电脑] 配置定时任务..."
BACKUP_JOB="30 8 * * * cd ${REMOTE_DIR} && bash backup.sh >> ${REMOTE_DIR}/logs/backup.log 2>&1"
EXISTING_CRON="$(crontab -l 2>/dev/null || true)"
NEW_CRON="${EXISTING_CRON}"
if ! echo "${NEW_CRON}" | grep -q "backup.sh"; then
NEW_CRON="${NEW_CRON}"$'\n'"${BACKUP_JOB}"
echo " [新电脑] 已添加每日备份定时任务"
fi
echo "${NEW_CRON}" | crontab -
echo " [新电脑] 定时任务配置完成"
REMOTE_CRON
ok "新电脑定时任务配置完成"
# ================================================================
# 9. 重启小龙虾
# ================================================================
info "9/9 重启新电脑小龙虾..."
ssh "${REMOTE_USER}@${REMOTE_IP}" << 'REMOTE_OPENCLAW'
set -euo pipefail
echo " [新电脑] 重启小龙虾..."
if command -v openclaw &>/dev/null; then
openclaw restart 2>/dev/null || echo " [新电脑] openclaw restart 可能需要手动确认"
echo " [新电脑] 小龙虾已重启"
else
echo " [新电脑] 未安装 openclaw 命令,跳过"
fi
REMOTE_OPENCLAW
ok "迁移流程全部完成!"
# ================================================================
rm -f "${SQL_DUMP}"
# ================================================================
clear
echo -e "${GREEN}============================================${NC}"
echo -e "${GREEN} 迁移完成!${NC}"
echo -e "${GREEN}============================================${NC}"
echo ""
echo -e " 数据平台: ${CYAN}http://${REMOTE_IP}:${APP_PORT}${NC}"
echo -e " 项目路径: ${REMOTE_DIR}"
echo ""
echo -e " ${YELLOW}定时任务:${NC}"
echo " 自动更新: 每天 7:00 / 12:00 / 18:00"
echo " 每日备份: 每天 8:30"
echo ""
echo -e " ${YELLOW}验证:${NC} 浏览器打开 http://${REMOTE_IP}:${APP_PORT}"
echo ""
echo -e " ${YELLOW}后期升级:${NC}"
echo " 旧电脑改完代码后一键打包升级:"
echo " cd ${PROJECT_DIR}"
echo " tar czf /tmp/upgrade.tar.gz . --exclude=venv --exclude=.git --exclude=__pycache__ --exclude=logs --exclude=backups"
echo " scp /tmp/upgrade.tar.gz ${REMOTE_USER}@${REMOTE_IP}:/tmp/"
echo " ssh ${REMOTE_USER}@${REMOTE_IP} 'cd ${REMOTE_DIR} && tar xzf /tmp/upgrade.tar.gz && kill \$(lsof -t -i:18888) 2>/dev/null; sleep 1; nohup venv/bin/gunicorn -w 4 -b 0.0.0.0:18888 --timeout 120 app:app >/dev/null 2>&1 &'"
echo ""
echo -e " ${GREEN}旧电脑(开发)不受影响。${NC}"