这次本来只是想搭一个简单博客,最后绕了一圈:从 VPS 上跑服务,改成静态博客;从自研 Astro + Notion,改成基于 otoyo/astro-notion-blog;再补上 Cloudflare Pages 和 Notion Webhook。过程有点折腾,但最后留下来的方案其实很简单。
最终方案
现在博客的核心链路是:
- 在 Notion 数据库里写文章。
- 文章勾选 Published,并设置 Slug、Date、Tags、Excerpt。
- Notion Webhook 把更新事件发给 Cloudflare Worker。
- Worker 做事件去重和短时间合并,然后触发 Cloudflare Pages Deploy Hook。
- Cloudflare Pages 拉取 GitHub 上的 Astro 项目,读取 Notion 内容,生成静态站点。
- blog.1891189.xyz 提供网页,/feed 提供 RSS。
这个方案里,VPS 不参与博客发布。它不需要常驻 Node 服务,不占内存,也不需要自己维护数据库、反代、证书或备份。
为什么最后选 otoyo/astro-notion-blog
一开始我更倾向自己写一个轻量 Astro + Notion 项目,因为可控。但实际评估下来,自己维护 Notion block 渲染并不划算。
otoyo/astro-notion-blog 已经解决了很多麻烦事:
- Notion 数据库字段模型比较完整。
- 支持文章、标签、分页、RSS。
- 支持较多 Notion block。
- 对图片、代码块、表格、嵌入内容的处理更成熟。
它原本的弱点是发布链路不够贴合我的需求。我的需求是 Notion 里一改,网站尽快更新,同时又不想维护额外服务。所以最后没有完全照搬它的部署方式,而是保留它的内容渲染能力,自己补了一层发布链路。
发布链路怎么优化
最终补上的发布链路是一个很小的 Cloudflare Worker。
它做三件事:
- 接收 Notion Webhook。
- 用 Durable Object 存 verification token、事件去重状态和待部署状态。
- 合并短时间内的多次更新,再触发 Cloudflare Pages Deploy Hook。
这样做的好处是:
- 更新比纯定时构建快。
- 多次连续编辑不会疯狂触发部署。
- Worker 和 Durable Object 都是 Cloudflare 托管,不需要我维护服务器。
- 仍然保留低频兜底构建,防止 webhook 漏事件。
中间踩过的坑
最大的坑是把一件简单事情过度工程化了。
一开始想得太全:RSS、Newsletter、VPS 资源、Notion 后台、静态构建、图片缓存、Cloudflare、Webhook、Durable Object、主题风格都一起考虑。每一件事单独都不复杂,放在一起就会变得很烦。
另一个坑是 Notion Webhook verification token 的存储。Cloudflare Cache 不适合做这种需要一致读取的状态存储。后来改成 Durable Object,问题才稳定下来。
还有一个细节是 webhook URL。Notion 后台填的是干净 URL,所以 Worker 必须能处理没有 query secret 的 Notion 事件。长期更严格的做法是配置 Notion verification token 做签名校验;现在的 Worker 已经保留了这条路径。
现在这套是否优雅
结论是:算比较优雅,但不是极简。
它优雅的地方在于职责分清楚了:
- Notion 只负责写作后台。
- Astro 只负责静态生成。
- GitHub 只负责代码版本。
- Cloudflare Pages 只负责托管。
- Worker 只负责 webhook 到部署触发。
- VPS 完全退出博客链路。
不够极简的地方在于多了一个 Worker 和 Durable Object。但这是为了换来更快的 Notion 同步。如果只要省心,不追求及时,甚至可以删掉 webhook,只保留定时构建。
后续还能优化什么
短期最值得做的是三件事:
- 把 Notion verification token 设置成 Worker secret,启用严格签名校验。
- 把页面标题、描述、默认 OG 图换成正式内容。
- 写一篇真正的首篇文章,把当前测试文章删掉或改成草稿。
中长期再考虑:
- 增加旧 /rss.xml 到 /feed 的重定向。
- 增加 404 页面。
- 增加更好的默认封面图。
- 如果文章多了,再整理标签和导航。
最后留下来的原则
这次最大的经验是:博客系统不要追求全能,先保证写作路径短。
现在最重要的路径只剩下:打开 Notion,写文章,勾选 Published。剩下的构建、RSS、托管、证书、部署都交给 Cloudflare 和 GitHub。这样才接近我真正想要的状态:快、稳、省心。