# cube Fam 的小 app 平台。 ## 是什么 `cube` 是一个跑在 **`famzheng.me` 节点**(hostname `famzheng.com`,单节点 k3s + traefik + gitea,公网 IP `178.104.186.206`)上的小 app 平台,专门收纳 Fam 自己写的一堆小工具/玩具 web app。底层硬件、k3s、Gitea、act_runner 等基础设施详见 `~/.claude/memory/infra.md`。 主要任务:把目前散落在 `oci.euphon.net`(Oracle Cloud ARM VM)上**值得留下**的 Fam 个人小 app 迁过来。oci 主机本身不退役,留给 Hera 同学继续用。 设计目标:反 Karpathy "web app 像拼宜家家具" 的困境 —— 全部自有基础设施,**零跨 dashboard 配置**,新 app 上线压缩到 5 分钟内。 --- ## 平台约定 > 这是 cube 上所有 app 的"宪法",所有 app 必须遵守,破例必须改这份文档并经 Fam 拍板。 ### 部署目标 单一目标:famzheng.me 节点的 k3s(`kubectl context default`),不双轨。 - 每 app 一个 k8s namespace(ns 名 = app 名,不加 cube- 前缀) - traefik ingress + 通配符 LE 证书自动签 ### 域名 - `.famzheng.me`,wildcard A 记录已配,**零 DNS 操作** - 不嵌 `cube` 子域(冲突检查 = 起新 ingress 时 traefik 自然报错,不需要额外心智) - 旧域名(如 `portfolio.oci.euphon.net`)让 oci ingress 兜底 308 redirect 到新地址,过渡期后下掉 ### 后端:Rust + Axum,每 app 独立仓库 - gitea repo `fam/`,单 axum 服务 - 公共代码通过 `cube-core` crate 复用:`cube-core = { git = "https://famzheng.me/gitea/fam/cube-core", tag = "v0.x" }` - `cube-core` 提供: - `/healthz` router(200 = ok) - `ServeDir` 静态前端 fallback 到 `index.html` - `tracing` 配 JSON stdout - SIGTERM graceful shutdown - env → struct 配置加载(`envy` crate) - 业务 app 只写 `/api/*` 路由 + handler: ```rust Router::new() .merge(cube_core::base("dist")) .nest("/api", api_routes()) ``` - 不上 cargo workspace —— 每 app 一个 repo 彻底分 ### 前端:Vite + Vue 3 - 默认栈:**Vite + Vue 3 + TypeScript + Pinia + Vue Router** - 选 Vue 而不是 Svelte 的原因:AI(Claude / GPT)写 Vue 3 `