为什么我把博客从云服务器搬到了 Astro + Cloudflare
一台 2C2G 的云主机每年要花掉几百块,只为了跑一个访问量两位数的博客。于是我把它拆成了静态优先的 Astro + 边缘函数 + 托管数据库。
起因:一台闲着也费钱的服务器
这个博客原来的架构非常土:一台 2 核 2G 的云主机,跑着 Nginx + Docker 里的 Node 进程 + 一个自建的 SQLite 文件。功能上没什么问题,但它有三个让我越来越难受的地方:
- 成本与流量脱钩。一年几百块的服务器费用,访问量常年两位数。
- 运维是纯负债。系统要打补丁、证书要续期、磁盘满了要清日志。每次收到告警我都要想一下「这个博客到底值不值得我花时间」。
- 冷启动很尴尬。Node 进程偶尔被 OOM 掉,第一个访问的人要等好几秒。
搬家的核心思路只有一句话:把「必须常驻」的部分干掉。
新架构:三层拆解
拆完之后是这样:
| 层 | 原来 | 现在 |
|---|---|---|
| 页面渲染 | 常驻 Node 进程 | Cloudflare Pages Functions(按需执行,毫秒级冷启动) |
| 数据 | 自建 SQLite 文件 | Cloudflare D1(托管 SQLite,按行读写计费) |
| 文件 | 服务器本地磁盘 + Nginx 直接返回 | Cloudflare R2(对象存储,出网流量免费) |
关键收益是 没有常驻进程。没人访问的时候,整个系统就是零计算成本,只有 D1 里的几 KB 数据和 R2 里的几十 MB 图片在计费。
为什么是 Astro 而不是纯静态生成器
很多人第一反应是「博客嘛,Hexo / Hugo 静态生成就够了,干嘛还上 SSR」。
静态生成确实是最省的方案,但它解决不了我的三个硬需求:
- 文章要能在后台写完立刻发布,而不是本地
hexo new+git push等 CI。 - 要能存草稿,而且草稿不能让搜索引擎和访客看到。
- 要能登录,后台得有个密码门。
这三件事都需要服务端。而 Astro 的好处是它同时给你两种模式:
src/pages/index.astro → 默认 SSR(要读 D1)
src/pages/about.astro → 加一行 export const prerender = true 就变成静态
也就是说,我可以在同一个项目里,把「关于页」这种几乎不变的内容静态化,把「文章列表」这种要实时读库的保持动态。这个粒度控制是我最后选它的决定性原因。
代码长什么样
在 Astro 里读取 D1 绑定,语法非常朴素——绑定挂在 locals.runtime.env 上:
const { env } = Astro.locals.runtime;
const { results } = await env.DB
.prepare('SELECT id, slug, title, summary, published_at FROM posts WHERE status = ? ORDER BY published_at DESC LIMIT ?')
.bind('published', 10)
.all();
env.DB 就是 wrangler.toml 里声明的那行绑定:
[[d1_databases]]
binding = "DB"
database_name = "blog-db"
database_id = "你的-database-id"
开发的时候,Astro 的 Cloudflare 适配器会通过 platformProxy 起一个本地 miniflare 环境,所以 npm run dev 读的是一份本地 SQLite 文件,跑 wrangler d1 execute --remote 才会打到线上——不用为了调试去污染生产数据。
搬家之后最爽的三件事
第一,发布变成了一件没有心理负担的事。 以前改一个错别字要经历「登录服务器 → 改文件 → reload」,现在打开 /admin 写完点保存就完了。
第二,成本曲线被压平了。 免费额度覆盖了我全部的使用量:D1 每天 500 万行读、R2 每月 1000 万次 A 类操作、Pages 每月 500 次构建。
第三,不再有「服务器在跑但没人访问」的荒诞感。
代价
当然不是白拿的,也有代价:
- 计时精度受限于边缘环境。Worker 有 CPU 时间限制(免费版每次请求 10ms CPU),所以别指望在请求里做重量级的数据处理。
- 没有常驻内存缓存。跨请求的状态必须放 D1 / KV / R2。
- 本地和生产环境有差异。
astro dev的 miniflare 和真实的 Worker 运行时偶尔会在细节上不一致,上线前最好wrangler pages dev ./dist跑一遍。
但对我这个规模的博客来说,这些限制一个都碰不到。选型的关键从来不是「最强的方案」,而是「最不容易在半年后变成负担的方案」。
这篇之后我会陆续把 D1、R2、边缘环境下的登录认证分别写一遍,作为搬家过程的完整记录。