14 KiB
Executable File
ChuBlog — 项目规划
状态:规划草案 v1.0 · 2026-10-15
定位:自托管个人技术博客;Markdown 文件是内容源,Git 管理版本,ChuSQL 提供可重建的内容索引。
1. 目标与原则
- 面向个人作者,支持公开阅读、文章归档、标签、代码高亮、目录、SEO、RSS 和深色模式。
- 管理员可在经过认证的后台上传 Markdown、预览、修改元数据、发布、撤回与删除文章;也支持本地 Git 工作流。
- Git 仓库内的 Markdown 与资源文件是唯一权威内容源;ChuSQL 不保存唯一一份正文,只维护可重建索引。
- 未授权用户不得发布页面、提交到内容仓库或触发任意服务器 Git 命令。
- 保持 MVP 小而可靠;不引入公共用户注册、评论、插件市场、队列/微服务或复杂角色系统。
- ChuSQL 暂不视为已通过生产验证的数据库;博客即使索引丢失,也能从 Git 恢复文章。
2. 技术栈
| 层 | 选型 | 职责 |
|---|---|---|
| 站点 | Astro + TypeScript | 内容页面、按需服务端渲染、SEO、RSS |
| 样式 | Tailwind CSS | 响应式设计、暗色模式 |
| Markdown | Astro Markdown 管线(remark/rehype、Shiki) | Markdown/Frontmatter 解析、代码高亮 |
| 后端 | Rust + Axum + Tokio + Serde | 管理员接口、认证、上传校验、Git 操作、索引同步 |
| 数据库 | ChuSQL | 已发布文章元数据、标签、搜索索引(按当前能力逐步实现) |
| DB 客户端 | chusql-rs(独立 crate) |
ChuSQL 网络协议连接、查询、错误处理 |
| 反向代理 | Caddy | HTTPS、请求体限制、路由 |
| 运行 | Debian + Docker Compose | 管理服务与持久卷 |
| 版本控制 | Git | 文章与图片的版本记录、审计与恢复 |
不自行编写 Markdown 语法解释器。MVP 禁止文章中的原始 HTML 或采用严格清理策略;默认不启用任意 MDX/JS 组件,因为上传文档不能成为服务器执行代码的入口。
3. 系统架构
读者浏览器 ── HTTPS ── Caddy ── Astro(公共页面)
│
├─ 只读文章文件 / content(挂载)
└─ Axum 只读 API(必要时)── ChuSQL(索引)
管理员浏览器 ── HTTPS ── Caddy ── Axum(后台 API)
│
├─ 管理员认证 / CSRF / 限流
├─ Markdown 校验及暂存
├─ 受控 Git 内容仓库
└─ 索引同步 ── chusql-rs ── ChuSQL
管理员本地编辑器 ── Git 受保护分支 / 仓库同步流程 ── 内容仓库
- 只暴露 80/443 TCP;Axum、Astro 与 ChuSQL 使用私有 Docker 网络。
- 现有 P2P 服务可独立继续使用 UDP 7001,互不影响。
- 不允许用户请求决定任意磁盘路径、Git 仓库地址、Git 参数或 shell 命令。
- Astro 若需上传后立即生效,使用按需 SSR 读取受控的内容快照;不要依赖仅构建时扫描的静态内容集合。若改用纯静态生成,则明确采用“提交后重新构建并原子部署”的发布策略。MVP 选择 SSR + 已发布内容快照。
4. 内容模型与存储布局
chublog/
├── apps/
│ ├── web/ # Astro 站点
│ └── api/ # Axum 后台与只读 API
├── crates/
│ └── chusql-rs/ # 若尚无独立仓库,可先工作区开发再拆分
├── content/ # 独立 Git 仓库或子目录(受控工作树)
│ ├── posts/
│ │ └── haskell-monad/
│ │ ├── index.md
│ │ └── cover.webp
│ └── .gitignore
├── deploy/
│ ├── compose.yaml
│ └── Caddyfile
└── PLAN.md
文章 Frontmatter 规范示例:
---
title: "Haskell Monad 入门"
slug: "haskell-monad"
date: "2026-10-15"
updated: "2026-10-15"
status: "published"
tags: ["Haskell", "Functional Programming"]
description: "Monad 的基础概念"
---
# Haskell Monad 入门
正文……
slug是唯一的 URL 标识,仅允许小写英文字母、数字、短横线,校验长度和保留名称。- 文件路径由服务端基于已校验 slug 固定计算;禁止
../、绝对路径、符号链接和路径穿越。 status取draft | published;草稿不可被未授权访问或从公开索引枚举。- 图片仅允许必要类型(如 PNG/JPEG/WebP),按真实文件内容与尺寸校验,限制单文件和文章总大小。SVG 暂不开放后台上传。
- 内容文件和 Frontmatter 是权威信息;ChuSQL 中的记录可由全量扫描重新建立。
5. Git 内容管理工作流
5.1 后台上传与发布
- 管理员登录,上传
.md与附属图片;后端检查会话、CSRF 与限流。 - 在隔离的暂存目录校验文件、解析 Frontmatter、检查重复 slug、限制大小和 Markdown 语法范围。
- 展示预览;管理员明确点击“发布”。预览默认不公开。
- 服务端通过受控文件操作写入仓库指定目录,创建 Git commit(提交者为固定服务身份,日志可附管理员操作 ID)。
- 提交成功后生成/切换已发布内容快照,并更新 ChuSQL 索引;公开页面仅读取已发布快照。
- 若索引更新失败,保留 Git 提交和待同步状态,由可重复执行的扫描任务恢复,不得静默显示“全部成功”。
5.2 本地 Git 编写
- 管理员可以在本地仓库编辑 Markdown,向受保护的主分支推送,或通过 PR 合并。
- 推荐在 CI 检查 Frontmatter、路径、大小、图片、链接及危险内容;只有已认证维护者可合并。
- 服务器采用只读拉取/受控部署,不接受互联网匿名推送;可使用带最小权限的部署凭证。
- 双入口写入存在冲突风险:MVP 应只开放一个写入主入口。建议首先采用“后台上传写入本地 Git 仓库”,后续引入远端同步时再明确由 CI 部署作为唯一发布入口;或者反过来完全让后台创建 PR。禁止两个入口不加协调地向同一工作树写入。
5.3 更新、撤回、删除
- 更新是新的 Git commit;保留文章稳定 slug,必要时配置显式重定向。
- 撤回把
status改为draft,新快照不可公开访问。 - 删除从当前版本移除,但 Git 历史可能仍含内容;对于秘密泄露需要额外执行历史清理与凭证轮换,不能认为删除 commit 就彻底清除。
- 上传的草稿与私有资源必须与公开静态目录隔离,避免直链泄露。
6. 身份认证与抗垃圾页面
MVP 采用单管理员、无公开注册、无公开投稿。 未登录者没有任何创建、编辑、上传或 Git 写权限。这比单纯依靠验证码或限流更能从根源上避免垃圾页面泛滥。
安全控制:
- 管理员账户配置在受保护的服务端环境或安全存储中;口令以 Argon2id 等成熟密码哈希存储,绝不保留明文。
- 登录成功后发放服务端会话;Cookie 使用
HttpOnly、Secure、SameSite,设置到期时间和退出失效机制。生产建议支持 TOTP 2FA 或使用成熟身份代理实现 MFA。 - 所有状态变更接口强制验证身份与 CSRF(包括上传、提交、发布和删除);校验
Origin,设置合理 CORS 策略。 - 登录端点按 IP 与账户维度限流、失败退避和审计;上传限制文件大小、数量、总磁盘配额、请求频率、并发和执行耗时。
- 反向代理和 API 分层限制请求体大小;服务仅接受预期 MIME 与文件结构;禁止 HTML/脚本执行、可疑链接协议与不受控资源嵌入。
- Git 命令通过固定参数的进程 API 执行,不用拼接 shell 字符串;Git 工作树不允许访问任意仓库 hook,服务运行身份权限最小化。
- 公开内容启用合理 CSP、HTML 清理、链接安全属性;后台不暴露到不必要的外部域名。
- 采用日志审计:谁在什么时候上传、预览、发布、撤回、删除,以及对应 commit hash;不要记录口令或会话令牌。
若以后支持访客投稿:所有投稿必须进入待审核区,经管理员人工批准后才能进入正式 Git 分支;不得让访客直接触发公开发布。
7. API 草案
| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
POST |
/api/admin/login |
公共、限流 | 管理员登录 |
POST |
/api/admin/logout |
管理员 + CSRF | 注销会话 |
GET |
/api/posts |
公共 | 查询已发布文章元数据 |
GET |
/api/posts/:slug |
公共 | 已发布文章信息(或由 Astro 直接读取文件) |
POST |
/api/admin/uploads |
管理员 + CSRF | 上传临时文件、验证 |
POST |
/api/admin/posts/preview |
管理员 + CSRF | 安全预览 |
POST |
/api/admin/posts/publish |
管理员 + CSRF | 固定目录落盘并 Git 提交 |
PATCH |
/api/admin/posts/:slug |
管理员 + CSRF | 更新元数据/内容 |
POST |
/api/admin/posts/:slug/unpublish |
管理员 + CSRF | 撤回文章 |
DELETE |
/api/admin/posts/:slug |
管理员 + CSRF | 删除当前版本 |
POST |
/api/admin/index/rebuild |
管理员 + CSRF | 从 Git 内容重建 ChuSQL 索引 |
API 路由仅为计划,后续以实现的最小接口为准;对发布、更新、删除操作加互斥与幂等处理,防止并发提交损坏仓库状态。
8. ChuSQL 集成与一致性
MVP 仅需要 posts 元数据与 tags,字段例如 slug, title, description, status, published_at, updated_at, path, git_commit。字段类型、DDL、过滤和分页查询应按现有 ChuSQL 协议确定,不能预设兼容 PostgreSQL 或 SQLx。
chusql-rs第一版支持:连接、超时、查询/执行、结果与类型映射、错误处理、断线识别、集成测试。- 不依赖目前未实现或未经验证的 ChuSQL 多语句事务;应用端以 Git 快照为权威,数据库仅做派生索引。
- 每次发布记录 Git commit hash,索引带对应内容版本号。建立独立的
rebuild-index命令与定期一致性检查。 - ChuSQL 不可用时,已生成的公开内容快照仍能被读取;列表、标签等可从文件快照构建简易只读索引。禁止在数据库错误时覆盖或删除文章文件。
- 上传发布时采用严格顺序和可恢复状态:校验 → 暂存 → Git commit → 更新已发布快照 → 尝试索引同步;出错后可依据 commit 重新同步。
- 文章页面不要因 ChuSQL 宕机而泄露内部错误或凭证。
9. 实施阶段与验收
Phase 0 — 先验证接口
- 检查 ChuSQL 服务端网络协议、查询语法和持久化行为。
- 决定 Astro SSR 在容器内读取哪个受控内容目录。
- 确定 Git 仓库部署路径、最小权限和快照切换方式。
Phase 1 — 纯文件博客 MVP
- Astro 页面:首页、文章详情、标签、归档、404、暗色模式。
- Markdown + Frontmatter 校验、Shiki 代码高亮、文章目录。
- Astro SSR 读取已发布内容快照;提供 RSS、sitemap 和 SEO 元信息。
- 测试异常文件、超大文件和 XSS 内容不会被执行。
Phase 2 — 后台 + Git 发布
- 单管理员认证、会话与 CSRF。
- 上传、预览、发布、编辑、撤回、删除。
- 每次发布产生可追踪的 Git commit;冲突与重复提交有明确错误反馈。
- 通过限流、文件配额、路径校验和无公开注册测试。
Phase 3 — ChuSQL 驱动与索引
- 开发
chusql-rs最小客户端及协议测试。 - 建立文章元数据表、查询接口与索引同步。
- 完成从 Git 仓库重建索引的命令与故障注入测试。
- 验证 ChuSQL 故障期间公开阅读不中断、恢复后索引一致。
Phase 4 — 部署与运维
- Docker Compose、Caddy TLS、仅开放必要公网端口。
- 持久化 Git 内容与资源;数据库卷、日志独立管理。
- 备份 Git 仓库(含远端镜像)与上传资源;定期进行真实恢复演练。
- 监测磁盘、接口错误、登录失败、索引同步延迟。
- 更新依赖、最小容器权限、限制容器挂载与网络访问。
MVP 完成判定:未经认证无法写入或发布;管理员可上传并发布一篇 Markdown,页面即刻可读,Git 中有对应提交;重启容器后内容存在;故意停止 ChuSQL 后仍可浏览已发布文章;重新建立数据库后可重建索引;恶意路径、超大文件和脚本注入测试均不能成功。
10. 生产就绪与风险边界
- 文章内容生产可用性来自 Git、可恢复的文件快照、访问控制、备份及恢复演练,不取决于 ChuSQL 当前成熟度。
- ChuSQL 仍按实验性组件管理:在事务原子性、并发控制、进程崩溃恢复、备份/恢复、认证与长时间稳定性未经验证前,不作为任何不可重建数据的唯一存储。
- 文件与数据库之间不追求假想的跨系统原子事务,而采用幂等同步和可回放 Git 提交恢复一致性。
- 不把管理员凭证、Git 写入凭证或 ChuSQL 密码写入 Git 仓库、镜像层和日志。
11. 暂不纳入 MVP
- 访客注册、公开投稿、评论、点赞与复杂权限角色。
- 前端在线富文本编辑器、协同编辑和复杂草稿工作流。
- 全文搜索引擎、消息队列、分布式部署、对象存储、多租户。
- 自建 Markdown 解释器、通用插件机制和 ChuSQL ORM/SQLx 适配。
12. 近期第一步
优先确认 ChuSQL 现有协议,同时创建 Astro 静态界面与 Axum 认证/上传原型。先跑通管理员上传 → 校验 → Git 提交 → 公开页面读取文件,之后再接入 ChuSQL 元数据索引。这样即使数据库研发推迟,博客仍可独立推进。