#!/usr/bin/env bash set -e # ===== 斗鱼批量登录 Docker 部署脚本 ===== ROOT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$ROOT_DIR" if [ -f "$ROOT_DIR/.env" ]; then set -a # shellcheck disable=SC1091 source "$ROOT_DIR/.env" set +a fi APP_PORT="${APP_PORT:-8000}" # ── 工具函数 ────────────────────────────────────────────── detect_compose() { if docker compose version &> /dev/null; then echo "docker compose" elif command -v docker-compose &> /dev/null; then echo "docker-compose" else echo "" fi } # ── 子命令 ────────────────────────────────────────────── cmd_deploy() { echo "" echo "==============================" echo " 斗鱼批量登录 - Docker 部署" echo "==============================" if ! command -v docker &> /dev/null; then echo "❌ 未安装 Docker,请先安装:" echo " curl -fsSL https://get.docker.com | sh" exit 1 fi COMPOSE=$(detect_compose) if [ -z "$COMPOSE" ]; then echo "❌ 未安装 docker compose,请先安装 Docker Compose" exit 1 fi echo " 使用: $COMPOSE" echo "" if [ -z "${YYB_WORKER_KEY:-}" ]; then echo "❌ 请先在 .env 中设置 YYB_WORKER_KEY" exit 1 fi if ! $COMPOSE config --quiet; then echo "❌ Docker Compose 配置无效,请检查 .env 中的必填变量" exit 1 fi # 创建数据和日志目录 mkdir -p data logs # 构建并启动 echo "正在构建应用镜像(首次构建约3-5分钟)..." # 生产部署不构建含大型开发依赖的 test 镜像;测试镜像仅在本地按需构建。 $COMPOSE build douyu-login echo "" echo "正在启动服务..." # 重新创建应用容器,确保生产环境不会沿用旧的 reload 配置。 $COMPOSE up -d --force-recreate echo "" echo "等待服务启动..." # 健康检查 for i in $(seq 1 15); do if curl -s "http://localhost:${APP_PORT}/api/health" | grep -q "ok" 2>/dev/null; then echo "" echo "==============================" echo " ✅ 部署成功!" echo "==============================" echo " 访问地址: http://localhost:${APP_PORT}" echo " 默认账号见环境变量 ADMIN_USERNAME/ADMIN_PASSWORD(未设置则为 admin/admin123)" echo "" echo " 查看应用日志: ./deploy.sh logs" echo " 查看容器输出: ./deploy.sh logs container" echo " 停止服务: $COMPOSE down" echo " 重启服务: $COMPOSE restart" echo " 重置数据: ./deploy.sh reset" echo "==============================" exit 0 fi echo " 等待中... ($i/15)" sleep 2 done echo "" echo "❌ 服务启动超时,查看日志:" $COMPOSE logs --tail 30 exit 1 } cmd_reset() { echo "" echo "==============================" echo " ⚠️ 重置所有数据" echo "==============================" echo "" echo " 将删除以下内容:" echo " • MySQL 数据卷" echo " • 应用宝 Worker 任务数据(扫码会话、二维码和订单记录)" echo " • 历史Cookie (data/cookies/)" echo " • 应用日志 (logs/)" echo " • Docker容器和镜像" echo "" # 交互确认 read -rp " 确认删除所有数据?输入 YES 继续: " confirm if [ "$confirm" != "YES" ]; then echo " 已取消" exit 0 fi COMPOSE=$(detect_compose) # 停止并删除容器 if [ -n "$COMPOSE" ]; then echo " 停止并删除容器..." $COMPOSE down --volumes --rmi local 2>/dev/null || $COMPOSE down --volumes 2>/dev/null || true fi # 删除数据文件 echo " 删除旧 SQLite 数据..." rm -rf data/web.db data/web.db-shm data/web.db-wal echo " 删除Cookie..." rm -rf data/cookies/ echo " 删除应用宝 Worker 任务..." rm -rf data/yyb-worker-jobs/ data/yyb-worker-dev/ echo " 删除日志..." rm -rf logs/*.log # 删除其他临时文件 rm -rf data/accounts.json data/gui_state.json data/app.db 2>/dev/null || true echo "" echo "==============================" echo " ✅ 数据已重置" echo "==============================" echo " 运行 ./deploy.sh 重新部署" echo "==============================" } cmd_logs() { local mode="${1:-app}" if [ "$mode" = "app" ]; then local app_log app_log="$ROOT_DIR/logs/app-$(date '+%Y-%m-%d').log" mkdir -p "$ROOT_DIR/logs" echo "跟踪应用文件日志: ${app_log}(Ctrl+C 退出)" exec tail -n "${LOG_TAIL_LINES:-200}" -F "$app_log" fi if [ "$mode" != "container" ]; then echo "用法: ./deploy.sh logs [app|container]" exit 1 fi COMPOSE=$(detect_compose) if [ -z "$COMPOSE" ]; then echo "❌ 未检测到 docker compose" exit 1 fi $COMPOSE logs --tail "${LOG_TAIL_LINES:-200}" -f } cmd_migrate_mysql() { COMPOSE=$(detect_compose) if [ -z "$COMPOSE" ]; then echo "❌ 未检测到 docker compose" exit 1 fi if [ ! -f data/web.db ]; then echo "❌ 未找到 data/web.db,无法迁移 SQLite 数据" exit 1 fi echo "正在启动 MySQL..." $COMPOSE up -d mysql echo "等待 MySQL 就绪..." for i in $(seq 1 30); do if $COMPOSE exec -T mysql sh -c 'mysqladmin ping -h localhost -uroot -p"$MYSQL_ROOT_PASSWORD" --silent' >/dev/null 2>&1; then echo "MySQL 已就绪" break fi if [ "$i" = "30" ]; then echo "❌ MySQL 启动超时,查看日志:" $COMPOSE logs --tail 50 mysql exit 1 fi sleep 2 done echo "正在构建迁移运行镜像..." $COMPOSE build douyu-login echo "开始迁移 SQLite 到 MySQL..." $COMPOSE run --rm --no-deps douyu-login \ python scripts/migrate_sqlite_to_mysql.py --source /app/data/web.db } cmd_migrate() { COMPOSE=$(detect_compose) if [ -z "$COMPOSE" ]; then echo "❌ 未检测到 docker compose" exit 1 fi echo "正在启动 MySQL..." $COMPOSE up -d mysql echo "等待 MySQL 就绪..." for i in $(seq 1 30); do if $COMPOSE exec -T mysql sh -c 'mysqladmin ping -h localhost -uroot -p"$MYSQL_ROOT_PASSWORD" --silent' >/dev/null 2>&1; then break fi if [ "$i" = "30" ]; then echo "❌ MySQL 启动超时,查看日志:" $COMPOSE logs --tail 50 mysql exit 1 fi sleep 2 done echo "正在执行数据库迁移..." echo "正在构建最新应用镜像..." $COMPOSE build douyu-login $COMPOSE run --rm --no-deps douyu-login \ python -c 'from web.backend.database import run_migrations; run_migrations()' echo "✅ 数据库迁移完成" } cmd_stop() { COMPOSE=$(detect_compose) if [ -z "$COMPOSE" ]; then echo "❌ 未检测到 docker compose" exit 1 fi $COMPOSE down echo "✅ 服务已停止" } cmd_restart() { COMPOSE=$(detect_compose) if [ -z "$COMPOSE" ]; then echo "❌ 未检测到 docker compose" exit 1 fi # 重建镜像和应用容器,使新迁移文件与入口迁移逻辑都能生效。 $COMPOSE up -d --build --force-recreate douyu-login echo "✅ 服务已重建并重启(已自动检查数据库迁移)" } cmd_dev() { exec "$ROOT_DIR/dev.sh" } # ── 帮助 ────────────────────────────────────────────────── cmd_help() { echo "" echo "==============================" echo " 斗鱼批量登录 - 部署工具" echo "==============================" echo "" echo " 用法: ./deploy.sh <命令>" echo "" echo " 命令:" echo " (无参数) 构建并部署" echo " reset 删除所有数据并重置(需确认)" echo " migrate-mysql 先启动 MySQL 并迁移 data/web.db" echo " migrate 仅执行数据库结构迁移" echo " logs [app|container] 查看应用文件日志(默认)或容器输出" echo " stop 停止服务" echo " restart 重启服务" echo " dev 本地调试启动(后端 reload + 前端热更新)" echo " help 显示帮助" echo "" echo " 访问地址: http://localhost:${APP_PORT}" echo " 调试地址: http://localhost:5174" echo " 默认账号见环境变量 ADMIN_USERNAME/ADMIN_PASSWORD" echo "" } # ── 入口 ────────────────────────────────────────────────── case "${1:-}" in reset) cmd_reset ;; migrate-mysql) cmd_migrate_mysql ;; migrate) cmd_migrate ;; logs) shift; cmd_logs "${1:-app}" ;; stop) cmd_stop ;; restart) cmd_restart ;; dev) cmd_dev ;; help|-h) cmd_help ;; *) cmd_deploy ;; esac