fix: 隔离既有发布的数据库容器生命周期(09-05-existing-deploy-db-lifecycle-isolation)
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-09-05 21:02:58 +08:00
父节点 05d2a3f78a
当前提交 f223bfb72f
共修改 11 个文件,包含 822 行新增和 7 行删除
+83 -7
查看文件
@@ -248,7 +248,7 @@ cd "$REMOTE_DIR"
if [[ "$DEPLOY_DATA_MODE" == "initialize" ]]; then
mkdir -p "$POSTGRES_DATA_DIR" "$STORAGE_HOST_DIR"
else
elif [[ "$DEPLOY_DATA_MODE" == "existing" ]]; then
if [[ ! -d "$POSTGRES_DATA_DIR" || ! -f "$POSTGRES_DATA_DIR/PG_VERSION" ]]; then
echo "[ERROR] existing 模式要求 POSTGRES_DATA_DIR 已存在且包含 PG_VERSION" >&2
exit 1
@@ -257,6 +257,9 @@ else
echo "[ERROR] existing 模式要求 STORAGE_HOST_DIR 已存在" >&2
exit 1
fi
else
echo "[ERROR] DEPLOY_DATA_MODE 必须显式设为 existing 或 initialize" >&2
exit 1
fi
if [[ "$ENABLE_MINIO" == "1" ]]; then
mkdir -p deploy/trialrun/data/minio
@@ -312,23 +315,96 @@ run_logged_deploy_stage() {
echo ">>> 4.1 校验远端 compose 配置"
"${compose_cmd[@]}" "${profile_args[@]}" config >/dev/null
if ! command -v timeout >/dev/null 2>&1; then
echo "[ERROR] db_health_timeout_unavailable:缺少有界就绪检查工具,停止发布" >&2
exit 1
fi
echo ">>> 4.2 启动基础服务"
"${compose_cmd[@]}" up -d db
wait_for_database_health() {
if timeout --signal=KILL 120 bash -s -- "${compose_cmd[@]}" <<'DB_HEALTH'
set -euo pipefail
while true; do
if ! database_id="$("$@" ps -a -q db 2>/dev/null)"; then
echo "[ERROR] db_health_query_failed:无法查询目标数据库容器,停止发布"
exit 1
fi
if [[ ! "$database_id" =~ ^[a-f0-9]{12,64}$ ]]; then
echo "[ERROR] db_container_missing_or_ambiguous:目标数据库容器不存在或不唯一,停止发布"
exit 1
fi
if ! database_health="$(docker inspect --type container --format '{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}missing{{end}}' "$database_id" 2>/dev/null)"; then
echo "[ERROR] db_health_query_failed:无法读取目标数据库健康状态,停止发布"
exit 1
fi
case "$database_health" in
'running|healthy') exit 0 ;;
'running|starting') sleep 2 ;;
*)
echo "[ERROR] db_not_healthy:数据库未运行、不健康或缺少健康检查,停止发布;不会自动启动或修复"
exit 1
;;
esac
done
DB_HEALTH
then
echo "[PASS] 目标数据库健康检查通过;本次等待上限 120 秒"
else
local health_status=$?
if [[ "$health_status" == "124" || "$health_status" == "137" ]]; then
echo "[ERROR] db_health_timeout:数据库就绪检查超过 120 秒,停止发布;不执行后续 init 或应用切换" >&2
fi
return 1
fi
}
echo ">>> 4.2 按部署模式检查基础服务"
if [[ "$DEPLOY_DATA_MODE" == "initialize" ]]; then
"${compose_cmd[@]}" up -d db
fi
wait_for_database_health
if [[ "$ENABLE_MINIO" == "1" ]]; then
"${compose_cmd[@]}" "${profile_args[@]}" up -d minio minio_init
"${compose_cmd[@]}" "${profile_args[@]}" up -d --no-deps minio minio_init
fi
echo ">>> 4.3 构建最新 init 镜像"
run_logged_deploy_stage "build-init" "${compose_cmd[@]}" build init
echo ">>> 4.4 预检新配置并执行 init"
run_logged_deploy_stage "run-init" "${compose_cmd[@]}" run --rm -T --entrypoint sh init -lc 'cd /app/server && node -e '\''require("./src/config").getConfig()'\'' && npm run prisma:migrate:deploy && npm run seed:config && npm run seed:trialrun'
wait_for_database_health
run_logged_deploy_stage "run-init" "${compose_cmd[@]}" run --rm --no-deps -T --entrypoint sh init -lc 'cd /app/server && node -e '\''require("./src/config").getConfig()'\'' && npm run prisma:migrate:deploy && npm run seed:config && npm run seed:trialrun'
echo ">>> 4.5 构建并切换应用服务"
run_logged_deploy_stage "build-switch-server" "${compose_cmd[@]}" "${profile_args[@]}" up -d --build server
wait_for_database_health
run_logged_deploy_stage "build-server" "${compose_cmd[@]}" "${profile_args[@]}" build server
if [[ "$ENABLE_WORKER" == "1" ]]; then
"${compose_cmd[@]}" "${profile_args[@]}" up -d worker
wait_for_database_health
if ! worker_container_id="$("${compose_cmd[@]}" "${profile_args[@]}" ps -a -q worker)"; then
echo "[ERROR] worker_image_query_failed:无法检查 worker 容器,停止发布" >&2
exit 1
fi
worker_image_ready=0
if [[ -n "$worker_container_id" ]]; then
if [[ ! "$worker_container_id" =~ ^[a-f0-9]{12,64}$ ]] || ! worker_image_reference="$(docker inspect --type container --format '{{.Config.Image}}' "$worker_container_id" 2>/dev/null)"; then
echo "[ERROR] worker_image_query_failed:worker 容器不唯一或镜像引用不可读,停止发布" >&2
exit 1
fi
if [[ ! "$worker_image_reference" =~ ^[A-Za-z0-9][A-Za-z0-9._/:@-]*$ ]]; then
echo "[ERROR] worker_image_query_failed:worker 镜像引用无效,停止发布" >&2
exit 1
fi
if docker image inspect "$worker_image_reference" >/dev/null 2>&1; then
worker_image_ready=1
fi
fi
if [[ "$worker_image_ready" != "1" ]]; then
run_logged_deploy_stage "build-worker" "${compose_cmd[@]}" "${profile_args[@]}" build worker
fi
fi
wait_for_database_health
run_logged_deploy_stage "build-switch-server" "${compose_cmd[@]}" "${profile_args[@]}" up -d --no-build --no-deps server
if [[ "$ENABLE_WORKER" == "1" ]]; then
wait_for_database_health
"${compose_cmd[@]}" "${profile_args[@]}" up -d --no-build --no-deps worker
fi
echo ">>> 4.6 校验 Prisma migration status"