|
|
#!/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=chrome(Docker 内会启动失败),请删除该行后重跑"
|
|
|
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 更新,全程失败即中断)"
|