#!/usr/bin/env bash set -euo pipefail # ===== EternalAI 部署脚本 ===== # 每次部署时运行,拉取最新代码、安装依赖、迁移数据库、重启服务 # 用法: bash deploy/deploy.sh # ---- 颜色输出 ---- RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; } # ---- 配置 ---- APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" HEALTH_URL="http://localhost:3001" HEALTH_TIMEOUT=30 cd "$APP_DIR" info "应用目录: $APP_DIR" # ---- 前置检查 ---- if [[ ! -f .env ]]; then error ".env 文件不存在,请先运行 deploy/setup-server.sh" exit 1 fi if ! command -v pm2 &>/dev/null; then error "PM2 未安装,请先运行 deploy/setup-server.sh" exit 1 fi # ---- 拉取最新代码 ---- info "拉取最新代码..." git fetch --all git reset --hard origin/master info "当前版本: $(git rev-parse --short HEAD)" # ---- 安装依赖 ---- info "安装 npm 依赖..." npm install --production=false # ---- 生成 Prisma Client ---- info "生成 Prisma Client..." npx prisma generate # ---- 数据库迁移 ---- info "推送数据库 Schema..." npx prisma db push # ---- 创建日志目录 ---- mkdir -p logs # ---- 重启 PM2 进程 ---- info "重启 PM2 进程..." if pm2 describe eternalai &>/dev/null; then pm2 reload ecosystem.config.js --update-env info "PM2 进程已 reload" else pm2 start ecosystem.config.js info "PM2 进程已启动" fi pm2 save # ---- 健康检查 ---- info "健康检查 (${HEALTH_TIMEOUT}s 超时)..." ELAPSED=0 while [[ $ELAPSED -lt $HEALTH_TIMEOUT ]]; do HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_URL" 2>/dev/null || echo "000") if [[ "$HTTP_CODE" == "200" ]]; then info "健康检查通过 (HTTP $HTTP_CODE)" break fi sleep 2 ELAPSED=$((ELAPSED + 2)) echo -n "." done echo "" if [[ "$HTTP_CODE" != "200" ]]; then error "健康检查失败 (HTTP $HTTP_CODE),请检查日志: pm2 logs eternalai" exit 1 fi # ---- 完成 ---- echo "" info "============================================" info " 部署完成!" info "============================================" echo "" echo "版本: $(git rev-parse --short HEAD)" echo "分支: $(git branch --show-current)" echo "状态: pm2 status" echo "日志: pm2 logs eternalai" echo ""