📝 从一台小 VPS 到 Notion + Astro:这次博客搭建复盘

这次本来只是想搭一个简单博客,最后绕了一圈:从 VPS 上跑服务,改成静态博客;从自研 Astro + Notion,改成基于 otoyo/astro-notion-blog;再补上 Cloudflare Pages 和 Notion Webhook。过程有点折腾,但最后留下来的方案其实很简单。

最终方案

现在博客的核心链路是:

  1. 在 Notion 数据库里写文章。
  2. 文章勾选 Published,并设置 Slug、Date、Tags、Excerpt。
  3. Notion Webhook 把更新事件发给 Cloudflare Worker。
  4. Worker 做事件去重和短时间合并,然后触发 Cloudflare Pages Deploy Hook。
  5. Cloudflare Pages 拉取 GitHub 上的 Astro 项目,读取 Notion 内容,生成静态站点。
  6. 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。

它做三件事:

  1. 接收 Notion Webhook。
  2. 用 Durable Object 存 verification token、事件去重状态和待部署状态。
  3. 合并短时间内的多次更新,再触发 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,只保留定时构建。

后续还能优化什么

短期最值得做的是三件事:

  1. 把 Notion verification token 设置成 Worker secret,启用严格签名校验。
  2. 把页面标题、描述、默认 OG 图换成正式内容。
  3. 写一篇真正的首篇文章,把当前测试文章删掉或改成草稿。

中长期再考虑:

  • 增加旧 /rss.xml 到 /feed 的重定向。
  • 增加 404 页面。
  • 增加更好的默认封面图。
  • 如果文章多了,再整理标签和导航。

最后留下来的原则

这次最大的经验是:博客系统不要追求全能,先保证写作路径短。

现在最重要的路径只剩下:打开 Notion,写文章,勾选 Published。剩下的构建、RSS、托管、证书、部署都交给 Cloudflare 和 GitHub。这样才接近我真正想要的状态:快、稳、省心。