Files
cube/crates/cube-core/src/lib.rs
T
Fam Zheng 93b6fa3061
deploy cube / build-and-deploy (push) Has been cancelled
app #0: cube.famzheng.me 入口门户 + 平台脚手架
monorepo 第一刀:
- workspace + crates/cube-core(base router / healthz / ServeDir SPA fallback / JSON tracing / SIGTERM shutdown)
- apps/cube:axum 主程序 + Vite + Vue 3 + TS 门户(暗色调 + 渐变 logo + app 卡片网格)
- Dockerfile:scratch + musl 静态二进制,镜像 2.6MB
- k8s/:cube-cube ns + Deployment + Service + Ingress(cube.famzheng.me,traefik LE 自动签)
- registry:新增 registry.famzheng.me ingress 反代到 gitea 内置 container registry,
  自动化身份用 mochi(registry.famzheng.me/mochi/cube)
- CI:.gitea/workflows/deploy-cube.yml,host shell runner(gnoc),
  build → push → kubectl rollout 五步流水
- README:把宪法段改成 monorepo 模式 + monorepo 目录结构
- 新增宪法条款:前端视图状态走 URL(path + query)保证可 bookmark
2026-05-04 11:22:59 +01:00

59 lines
2.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! cube-core: 共享脚手架。所有 cube app 通过这个 crate 拿基础 router、tracing、shutdown。
use std::path::Path;
use axum::{routing::get, Router};
use tokio::net::TcpListener;
use tokio::signal;
use tower_http::services::{ServeDir, ServeFile};
use tower_http::trace::TraceLayer;
/// 拼一个带 healthz + 静态前端 SPA fallback 的基础 router。
///
/// `dist_dir` 是前端 vite build 输出目录(容器内一般是 `/dist`)。
pub fn base(dist_dir: impl AsRef<Path>) -> Router {
let dist = dist_dir.as_ref().to_path_buf();
let index = dist.join("index.html");
let static_svc = ServeDir::new(&dist).fallback(ServeFile::new(index));
Router::new()
.route("/healthz", get(healthz))
.fallback_service(static_svc)
.layer(TraceLayer::new_for_http())
}
async fn healthz() -> &'static str {
"ok"
}
/// 初始化 tracingJSON to stdout,吃 RUST_LOG env。
pub fn init_tracing() {
use tracing_subscriber::{fmt, EnvFilter};
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
fmt().json().with_env_filter(filter).init();
}
/// 起服务,绑定 0.0.0.0:port,挂 SIGTERM/SIGINT 优雅 shutdown。
pub async fn serve(app: Router, port: u16) -> std::io::Result<()> {
let addr = format!("0.0.0.0:{port}");
let listener = TcpListener::bind(&addr).await?;
tracing::info!(%addr, "cube app listening");
axum::serve(listener, app)
.with_graceful_shutdown(shutdown_signal())
.await
}
async fn shutdown_signal() {
let ctrl_c = async { signal::ctrl_c().await.expect("install ctrl_c handler") };
let term = async {
signal::unix::signal(signal::unix::SignalKind::terminate())
.expect("install SIGTERM handler")
.recv()
.await;
};
tokio::select! {
_ = ctrl_c => tracing::info!("ctrl-c received, shutting down"),
_ = term => tracing::info!("SIGTERM received, shutting down"),
}
}