关于 Lumo
Lumo 是一个用 Go 编写的开源 CMS。它想解决的是一个很具体的问题:把一套完整的建站系统,交付成单个可执行文件。
没有运行时依赖,没有容器编排,没有构建流水线。一个二进制、一个 PostgreSQL,拷到服务器上就能跑。
它解决什么问题
现成的 CMS 不是太少而是太多,所以更有意义的是说清楚这里做了哪几个判断。
后台嵌进二进制。 后台是一个 React 单页应用,但它不是单独的构建产物——它被编译进 Go 二进制里。上线不需要同时部署前端和后端,也不会出现「前端版本和后端接口对不上」这类只会在生产环境暴露的问题。
前台由服务端渲染。 访客看到的页面是 Go 模板渲染出来的 HTML,不是 SPA。登录、注册、找回密码、账户页这些关键表单都是原生 POST,关掉 JavaScript 也能用。这对搜索引擎和弱网环境都是更省事的做法。
主题走模板接口,不走插件。 主题包就是一堆 html/template 模板加一份声明文件。必需模板只有四个,缺一个会整页回退到内置主题,而不是报错或渲染出空白页。
插件目前不执行代码。 插件系统的第一期是纯声明式的:清单 + 设置 + 生命周期,没有代码执行。WASM 运行时在路线上,但不在现在。
技术底座
| 层 | 选型 |
|---|---|
| 语言 | Go 1.26+,全链路 -tags nodynamic |
| 数据库 | PostgreSQL 17+(pgx + bun + goose 迁移) |
| 后台前端 | React 19 + Vite + TypeScript strict + Tailwind v4 |
| 路由与接口 | chi 三平面路由 + huma,OpenAPI 3.1 由代码生成 |
| 前台渲染 | html/template + Hugo 式 layout / partial 约定 |
| 内容格式 | Markdown 与规范 HTML 并为一等公民 |
| 编辑器 | TipTap v3(块编辑)与 Milkdown 7(Markdown) |
后台的 TypeScript 类型从 OpenAPI 规范生成,不手写。规范与生成物都进版本库,所以前端构建不依赖后端在跑。
架构上几个刻意的决定
模块是编译期的。 十四个功能模块各自持有自己的数据库迁移和独立的版本表(goose_db_version_<模块>),彼此不引用内部实现,只通过 internal/app 的 Module 契约装配。cmd/lumo/modules.go 是唯一的装配点,顺序即依赖顺序。
接口分三个平面,前缀与鉴权策略固定。 后台面 console 默认强制认证;公开面 public 匿名可读已发布内容;扩展面 extension 留给插件的自定义模型。所有接口都经 huma 注册,错误一律是 RFC 9457 的 application/problem+json。
正文按权限净化。 没有 content:unsafe_html 权限的角色,正文在保存时就按允许列表净化;有这个权限的(默认只有管理员与超级管理员)才能写入可执行内容。把这条权限授予编辑,等于允许他构造针对管理员的脚本。
凭据加密入库。 SMTP 口令与对象存储密钥在后台填、用 AES-256-GCM 加密存下来,接口永不回传明文。主密钥是 data/secret.key。
数据库连接串只走环境变量。 这一条是硬线:DSN 不会出现在任何配置文件里,也不会出现在会被渲染或导出的内容里。首次安装时它写在 data/install.json(权限 0600),备份时要连 data/ 一起备——否则库里的那些口令解不开。
刻意不做的事
- 不做功能阉割版。 没有「社区版 / 专业版」的功能差。程序本体怎么用都行,商业使用也不收费。
- 不把使用者当收入来源。 项目未来的收入来自主题市场抽成和作者自己的付费主题,不来自站点运营者。
- 不追求做一站式平台。 不做建站托管服务,不做可视化拖拽编辑,不做多租户。
- 不为了兼容而兼容。 目前没有从其他 CMS 迁移的工具,也不打算做「假装别的系统的模板能直接跑」。
现在到哪一步
已经打了 v0.1.0 标签:九个开发阶段全部完成,十四个功能模块齐备,外部安全审查提出的 26 项问题全部处置。
但还没有经过生产环境检验,也仍然缺少自动化测试——原有用例已于 2026-09-15 整体清空,go test 现在只是空跑。欢迎试用与反馈,上生产请自行评估风险。缺什么、做到哪了,见路线图。
评论
还没有评论,来说两句。