优化启动脚本

This commit is contained in:
yml2213
2026-07-09 21:39:47 +08:00
parent 90fe910d1c
commit 3318ed18ee
+103 -6
View File
@@ -11,6 +11,7 @@ BACKEND_DATA_DIR="${PROJECT_ROOT}/apps/backend/data"
BACKEND_CONTAINER_UID=1001 BACKEND_CONTAINER_UID=1001
BACKEND_CONTAINER_GID=1001 BACKEND_CONTAINER_GID=1001
HEALTH_URL="" HEALTH_URL=""
READY_TIMEOUT="${READY_TIMEOUT:-120}"
log() { log() {
printf '\033[1;34m[deploy]\033[0m %s\n' "$*" printf '\033[1;34m[deploy]\033[0m %s\n' "$*"
@@ -60,6 +61,8 @@ validate_env_file() {
fail ".env 仍包含示例占位值,请替换后再部署。" fail ".env 仍包含示例占位值,请替换后再部署。"
fi fi
[[ "${READY_TIMEOUT}" =~ ^[1-9][0-9]*$ ]] || fail "READY_TIMEOUT 必须是正整数秒数,当前值:${READY_TIMEOUT}"
local site_addr local site_addr
site_addr="$(read_env_value CADDY_SITE_ADDR)" site_addr="$(read_env_value CADDY_SITE_ADDR)"
[[ -n "${site_addr}" ]] || fail ".env 缺少 CADDY_SITE_ADDR。" [[ -n "${site_addr}" ]] || fail ".env 缺少 CADDY_SITE_ADDR。"
@@ -100,28 +103,122 @@ ensure_data_dir() {
warn "sudo chown -R ${BACKEND_CONTAINER_UID}:${BACKEND_CONTAINER_GID} ${BACKEND_DATA_DIR}" warn "sudo chown -R ${BACKEND_CONTAINER_UID}:${BACKEND_CONTAINER_GID} ${BACKEND_DATA_DIR}"
} }
deploy_stack() { check_compose_config() {
log "检查 Docker Compose 配置"
docker compose config >/dev/null || fail "Docker Compose 配置校验失败。"
}
pull_base_images() {
log "拉取基础镜像" log "拉取基础镜像"
docker compose pull --ignore-buildable docker compose pull --ignore-buildable
}
log "构建并启动服务" build_images() {
if docker compose up -d --build; then log "构建后端镜像"
docker compose build backend || fail "后端镜像构建失败。"
log "构建 Web 镜像"
docker compose build web || fail "Web 镜像构建失败。"
}
wait_for_service() {
local service="$1"
local label="$2"
local attempt container_id status health_status
log "等待 ${label} 就绪"
for ((attempt = 1; attempt <= READY_TIMEOUT; attempt++)); do
container_id="$(docker compose ps -q "${service}" 2>/dev/null || true)"
if [[ -n "${container_id}" ]]; then
status="$(docker inspect -f '{{.State.Status}}' "${container_id}" 2>/dev/null || true)"
health_status="$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{end}}' "${container_id}" 2>/dev/null || true)"
if [[ -n "${health_status}" && "${health_status}" == "healthy" ]]; then
log "${label} 已就绪"
return
fi
if [[ -z "${health_status}" && "${status}" == "running" ]]; then
log "${label} 已启动"
return
fi
if [[ "${status}" == "exited" || "${status}" == "dead" ]]; then
break
fi
fi
sleep 1
done
print_diagnostics
fail "${label} 启动超时,请根据上面的日志排查。"
}
start_postgres() {
log "启动 PostgreSQL"
if docker compose up -d --no-deps postgres; then
wait_for_service postgres "PostgreSQL"
return return
fi fi
print_diagnostics print_diagnostics
fail "docker compose 启动失败,请根据上面的日志排查。" fail "PostgreSQL 启动失败,请根据上面的日志排查。"
}
run_database_migrations() {
log "执行数据库迁移"
if docker compose run --rm --no-deps backend node dist/db/migrate.js; then
log "数据库迁移完成"
return
fi
print_diagnostics
fail "数据库迁移失败,请根据上面的日志排查。"
}
restart_backend() {
log "重建并启动后端"
if docker compose up -d --no-deps --force-recreate backend; then
wait_for_service backend "后端"
return
fi
print_diagnostics
fail "后端启动失败,请根据上面的日志排查。"
}
restart_web() {
log "重建并启动 Web 入口"
if docker compose up -d --no-deps --force-recreate --remove-orphans web; then
wait_for_service web "Web"
return
fi
print_diagnostics
fail "Web 启动失败,请根据上面的日志排查。"
}
deploy_stack() {
check_compose_config
pull_base_images
build_images
start_postgres
run_database_migrations
restart_backend
restart_web
} }
wait_for_health() { wait_for_health() {
log "等待服务健康检查:${HEALTH_URL}" log "等待服务健康检查:${HEALTH_URL}"
for _ in $(seq 1 60); do for _ in $(seq 1 "${READY_TIMEOUT}"); do
if curl -fsS "${HEALTH_URL}" >/dev/null 2>&1; then if curl -fsS "${HEALTH_URL}" >/dev/null 2>&1; then
log "服务已就绪" log "服务已就绪"
return return
fi fi
sleep 2 sleep 1
done done
print_diagnostics print_diagnostics