优化启动脚本
This commit is contained in:
+103
-6
@@ -11,6 +11,7 @@ BACKEND_DATA_DIR="${PROJECT_ROOT}/apps/backend/data"
|
||||
BACKEND_CONTAINER_UID=1001
|
||||
BACKEND_CONTAINER_GID=1001
|
||||
HEALTH_URL=""
|
||||
READY_TIMEOUT="${READY_TIMEOUT:-120}"
|
||||
|
||||
log() {
|
||||
printf '\033[1;34m[deploy]\033[0m %s\n' "$*"
|
||||
@@ -60,6 +61,8 @@ validate_env_file() {
|
||||
fail ".env 仍包含示例占位值,请替换后再部署。"
|
||||
fi
|
||||
|
||||
[[ "${READY_TIMEOUT}" =~ ^[1-9][0-9]*$ ]] || fail "READY_TIMEOUT 必须是正整数秒数,当前值:${READY_TIMEOUT}"
|
||||
|
||||
local site_addr
|
||||
site_addr="$(read_env_value 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}"
|
||||
}
|
||||
|
||||
deploy_stack() {
|
||||
check_compose_config() {
|
||||
log "检查 Docker Compose 配置"
|
||||
docker compose config >/dev/null || fail "Docker Compose 配置校验失败。"
|
||||
}
|
||||
|
||||
pull_base_images() {
|
||||
log "拉取基础镜像"
|
||||
docker compose pull --ignore-buildable
|
||||
}
|
||||
|
||||
log "构建并启动服务"
|
||||
if docker compose up -d --build; then
|
||||
build_images() {
|
||||
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
|
||||
fi
|
||||
|
||||
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() {
|
||||
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
|
||||
log "服务已就绪"
|
||||
return
|
||||
fi
|
||||
sleep 2
|
||||
sleep 1
|
||||
done
|
||||
|
||||
print_diagnostics
|
||||
|
||||
Reference in New Issue
Block a user