#!/usr/bin/env bash # 代码/镜像更新(服务器上可选同步库结构) # 用法: # bash deploy/update-code-only-bt-host-mysql.sh # bash deploy/update-code-only-bt-host-mysql.sh --db-push # schema 有变更时 # # 特点:串行 build;默认不碰库;失败 fail-fast set -euo pipefail ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" COMPOSE_FILE="${ROOT_DIR}/deploy/docker-compose.bt-host-mysql.yml" ENV_FILE="${ROOT_DIR}/.env" DO_DB_PUSH=false for arg in "$@"; do case "$arg" in --db-push) DO_DB_PUSH=true ;; -h|--help) echo "用法: bash deploy/update-code-only-bt-host-mysql.sh [--db-push]" exit 0 ;; esac done RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log() { echo -e "${GREEN}[update-code]${NC} $*"; } warn() { echo -e "${YELLOW}[update-code]${NC} $*"; } err() { echo -e "${RED}[update-code]${NC} $*" >&2; } CURRENT_STEP="init" on_err() { local code=$? err "失败中断:步骤「${CURRENT_STEP}」退出码=${code}" exit "$code" } trap on_err ERR require_file() { local path="$1" if [[ ! -f "$path" ]]; then err "缺少文件: $path" exit 1 fi } run_step() { local name="$1" shift CURRENT_STEP="$name" log "→ ${name}" "$@" log "✓ ${name} 完成" } CURRENT_STEP="preflight" log "前置校验..." if [[ ! -f "$ENV_FILE" ]]; then err "缺少 .env,禁止继续" exit 1 fi if ! command -v docker >/dev/null 2>&1; then err "未安装 docker" exit 1 fi require_file "${ROOT_DIR}/src/app/api/mails/[id]/route.ts" require_file "${ROOT_DIR}/Dockerfile" require_file "${ROOT_DIR}/package.json" require_file "${ROOT_DIR}/pnpm-lock.yaml" log "前置校验通过" cd "$ROOT_DIR" compose=(docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE") export DOCKER_BUILDKIT=1 export BUILDKIT_MAX_PARALLELISM=1 run_step "停止 web/worker" \ "${compose[@]}" stop web worker run_step "构建 web" \ "${compose[@]}" build web run_step "构建 worker" \ "${compose[@]}" build worker run_step "启动全部服务" \ "${compose[@]}" up -d if [[ "$DO_DB_PUSH" == "true" ]]; then run_step "同步数据库结构(prisma db push)" \ "${compose[@]}" run --rm --no-deps web pnpm exec prisma db push --skip-generate else warn "跳过 db push(schema 无变更可忽略;有变更请加 --db-push)" fi CURRENT_STEP="校验容器状态" for svc in web worker; do state="$("${compose[@]}" ps --status running --services 2>/dev/null | grep -x "$svc" || true)" if [[ -z "$state" ]]; then err "服务未处于 running: ${svc}" exit 1 fi log "✓ ${svc} running" done CURRENT_STEP="done" trap - ERR log "完成(代码-only 更新)"