|
|
#!/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 更新)"
|