Hello, World

这是 Berrylium 的第一篇公开文章。

这个站点本身也是它的第一份正式记录:我用 Python 和 Pelican 生成静态博客,把页面发布到 Cloudflare Pages;评论系统则运行在 Cloudflare Python Worker 上,数据写入 D1,备份写入 R2。

这次完成了什么

这次上线的目标很简单:先做一个能长期维护、主要给自己写作使用的个人博客。

最终保留下来的设计是:

  • 正文用 Markdown 写在 Git 仓库里。
  • 静态页面由 Pelican 构建。
  • 前端保持现代化 RFC 文档风格。
  • 中英文文章可以共用同一个 doc_id,但不要求每篇都双语。
  • 评论按 doc_id 共享线程。
  • 评论立即展示,不做人工审核。
  • 评论者可以选择昵称,邮箱可选。
  • 回复通知通过 Resend 发送。
  • 评论 API 部署在 Cloudflare Python Worker。
  • D1 保存评论,R2 保存每日备份。
  • GitHub push 后自动触发检查和部署。

为什么是静态博客加动态评论

静态博客的好处是简单、稳定、便宜。文章本身是文件,版本历史在 Git 里,迁移成本低。

评论是动态数据,不适合塞进静态构建流程。所以它被拆成独立 API:页面可以静态发布,评论区滚动到可见位置后再加载。

这个拆分让系统边界更清楚:文章是内容,评论是服务。

上线过程中踩到的点

Cloudflare Pages 的自动构建一开始把整个仓库当成 Python 包安装,触发了 setuptools 的包发现错误。解决方式是在根 pyproject.toml 里明确声明这个仓库不是一个可安装 Python 包。

Cloudflare Python Worker 的免费计划还有 3 MiB 的 Worker 包体限制。最初使用 FastAPI、Pydantic 和 httpx,包体超限。后来把 Worker 改成轻量 ASGI 入口,保留必要的 Markdown 渲染和 HTML 清洗,最终部署包压缩后约 1.6 MiB。

本地 pywrangler dev 还会依赖 Cloudflare 的 Pyodide runtime 下载,在当前网络环境下不稳定。因此本地 smoke test 主要验证应用层行为,真正的运行时 smoke 放到线上 Worker 完成。

当前状态

现在,blog.rtly.me 已经能通过 Cloudflare Pages 自动部署静态站。

评论 API 绑定在:

https://blog.rtly.me/api/*

GitHub Actions 会在 main 分支 push 后执行:

  1. 静态站检查和发布构建。
  2. 评论 Worker 测试。
  3. 远端 D1 migration。
  4. 评论 Worker 自动部署。

这篇文章发布后,也会成为整条链路的一次真实验证。

下一步

后面要做的不是继续堆功能,而是开始正常使用它:写文章、接受评论、观察通知和备份是否稳定。

如果这个系统能支撑持续写作,它就已经完成了 MVP 的目标。