You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chajia/deploy/update-code-only-bt-host-my...

156 lines
4.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
# 代码/镜像更新(服务器上不改库)— 任一步失败立即中断
# 用法:
# 1) 本机 DataGrip 已执行 deploy/datagrip-manual-migrate-20260716.sql
# 2) 服务器bash deploy/update-code-only-bt-host-mysql.sh
#
# 特点:串行 build跳过 migrate/seed失败 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"
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}"
err "已停止继续执行(不会启动半成品镜像)。请根据上方日志修复后重跑本脚本。"
err "若容器已 stop修复后重新执行本脚本即可恢复。"
exit "$code"
}
trap on_err ERR
require_file() {
local path="$1"
if [[ ! -f "$path" ]]; then
err "缺少文件: $path"
exit 1
fi
}
require_env_key() {
local key="$1"
if ! grep -qE "^[[:space:]]*${key}=" "$ENV_FILE"; then
err ".env 缺少 ${key}(新功能不会生效)"
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 [[ ! -f "$COMPOSE_FILE" ]]; then
err "缺少 compose 文件: $COMPOSE_FILE"
exit 1
fi
if ! command -v docker >/dev/null 2>&1; then
err "未安装 docker"
exit 1
fi
if ! docker compose version >/dev/null 2>&1; then
err "需要 Docker Compose V2"
exit 1
fi
require_file "${ROOT_DIR}/app/api/flock/quotes/route.ts"
require_file "${ROOT_DIR}/workers/rpa/flock-freight.ts"
require_file "${ROOT_DIR}/workers/rpa/mothership-logged-in-quote.ts"
require_file "${ROOT_DIR}/Dockerfile"
require_file "${ROOT_DIR}/Dockerfile.worker"
require_file "${ROOT_DIR}/package.json"
require_file "${ROOT_DIR}/package-lock.json"
require_env_key "FLOCK_RPA_ENABLED"
require_env_key "NEXT_PUBLIC_FLOCK_POLL_TIMEOUT_MS"
require_env_key "DATABASE_URL"
require_env_key "JWT_SECRET"
if grep -qE "^[[:space:]]*RPA_BROWSER_CHANNEL=chrome" "$ENV_FILE"; then
err ".env 存在 RPA_BROWSER_CHANNEL=chromeDocker 内会启动失败),请删除该行后重跑"
exit 1
fi
# 可用内存过低时警告(不强制中断,避免误杀)
if command -v free >/dev/null 2>&1; then
avail_kb="$(free -k | awk '/^Mem:/{print $7}')"
if [[ -n "${avail_kb:-}" && "$avail_kb" -lt 400000 ]]; then
warn "可用内存偏低(约 $((avail_kb / 1024))MB构建可能 OOM建议先 stop 其他重负载或加 Swap"
fi
fi
log "前置校验通过"
cd "$ROOT_DIR"
compose=(docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE")
export DOCKER_BUILDKIT=1
export BUILDKIT_MAX_PARALLELISM=1
# ---------- 串行更新(任一步失败由 trap 中断)----------
run_step "停止 next-app/rpa-worker/scheduler" \
"${compose[@]}" stop next-app rpa-worker scheduler
run_step "构建 next-app" \
"${compose[@]}" build next-app
run_step "构建 rpa-worker" \
"${compose[@]}" build rpa-worker
run_step "构建 scheduler" \
"${compose[@]}" build scheduler
run_step "启动全部服务" \
"${compose[@]}" up -d
CURRENT_STEP="校验容器状态"
log "→ 校验容器状态"
"${compose[@]}" ps
# 关键服务必须处于 running
for svc in next-app rpa-worker scheduler redis; do
state="$("${compose[@]}" ps --status running --services 2>/dev/null | grep -x "$svc" || true)"
if [[ -z "$state" ]]; then
err "服务未处于 running: ${svc}"
err "查看日志: ${compose[*]} logs --tail 80 ${svc}"
exit 1
fi
log "${svc} running"
done
CURRENT_STEP="done"
trap - ERR
warn "库结构须已在 DataGrip 用 SQL 改完(本脚本不碰库)"
warn "以后不要再跑 install-bt-host-mysql.sh会自动 migrate"
warn "建议清报价缓存:"
echo " ${compose[*]} exec redis redis-cli FLUSHDB"
log "完成(代码-only 更新,全程失败即中断)"