#!/bin/bash # BillAI 自动部署脚本 # 此脚本由 Gitea webhook 触发,自动执行 git pull 并重新构建部署 set -e REPO_ROOT="/app" LOG_FILE="/tmp/billai_deploy.log" # 可由 webhook 传入:GIT_REF=refs/heads/main 或 refs/heads/master GIT_REF="${GIT_REF:-}" GIT_COMMIT="${GIT_COMMIT:-}" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log() { echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE" } error() { echo -e "${RED}[错误]${NC} $1" | tee -a "$LOG_FILE" exit 1 } success() { echo -e "${GREEN}[成功]${NC} $1" | tee -a "$LOG_FILE" } log "==========================================" log "🚀 BillAI 自动部署开始" log "==========================================" # 进入仓库目录 cd "$REPO_ROOT" || error "无法进入仓库目录: $REPO_ROOT" log "📁 工作目录: $(pwd)" if [ -n "$GIT_REF" ]; then log "🌿 触发分支: $GIT_REF" fi if [ -n "$GIT_COMMIT" ]; then log "🧾 触发提交: ${GIT_COMMIT:0:7}" fi # 拉取最新代码 log "📥 正在拉取最新代码..." if ! git fetch origin; then error "git fetch 失败" fi # 选择部署分支(优先使用 webhook 传入的 ref) DEPLOY_BRANCH="" if [ "$GIT_REF" = "refs/heads/main" ]; then DEPLOY_BRANCH="main" elif [ "$GIT_REF" = "refs/heads/master" ]; then DEPLOY_BRANCH="master" fi # 兜底:按远端分支存在性选择(兼容仓库从 master 切到 main) if [ -z "$DEPLOY_BRANCH" ]; then if git show-ref --verify --quiet refs/remotes/origin/main; then DEPLOY_BRANCH="main" else DEPLOY_BRANCH="master" fi fi log "🌿 部署分支: $DEPLOY_BRANCH" if ! git reset --hard "origin/$DEPLOY_BRANCH"; then error "git reset 失败" fi success "代码已更新" # 显示当前提交信息 log "📝 当前提交:" git log --oneline -1 # 检查 docker-compose 是否存在 if [ ! -f "docker-compose.yaml" ]; then error "docker-compose.yaml 不存在" fi log "🐳 开始热更新部署(不停机)..." # 定义需要重新部署的服务(排除 webhook 自身,否则会自杀) SERVICES="web server analyzer" # 拉取基础镜像更新 log "📦 检查基础镜像更新..." docker-compose pull mongodb mongo-express || true # 热更新:重新构建并替换容器(不停止旧服务,直接替换) log "🔨 热更新服务(构建 + 替换)..." if ! docker-compose up -d --build --force-recreate --no-deps $SERVICES; then error "Docker 热更新失败" fi # 清理旧的未使用镜像 log "🧹 清理旧镜像..." docker image prune -f || true # 等待服务启动 log "⏳ 等待服务启动..." sleep 5 # 检查服务健康状态 log "🏥 检查服务健康状态..." for i in {1..30}; do if curl -f http://localhost:8080/health > /dev/null 2>&1; then success "后端服务已启动" break fi if [ $i -eq 30 ]; then error "后端服务启动超时" fi sleep 1 done for i in {1..30}; do if curl -f http://localhost:3000 > /dev/null 2>&1; then success "前端服务已启动" break fi if [ $i -eq 30 ]; then error "前端服务启动超时" fi sleep 1 done log "==========================================" success "🎉 部署完成" log "==========================================" log "⏰ 完成时间: $(date +'%Y-%m-%d %H:%M:%S')" log "✅ 所有服务已启动并正常运行" log "" log "📍 访问地址:" log " 前端: http://localhost:3000" log " 后端: http://localhost:8080" log ""