不花一分钱,我把静态博客搭成了带在线后台的「动态站」
不少人对「自己搭博客」的印象停留在两选一:
- 要么上 WordPress / Typecho 这种动态博客 —— 得租一台服务器,年年掏钱,还要操心备份和安全;
- 要么用 Hexo / Hugo 这种静态博客 —— 托管免费,但只能本地写 Markdown、敲命令发布,换台电脑就抓瞎,写作体验像在做运维。
我最后的方案是:用静态站的成本,做出「动态站」的体验。
- 打开网页登录后台,在 Notion 风格的编辑器里写文章,截图直接粘贴上传;
- 点一下「发布」,一分钟后文章就在线上出现;
- 图床、评论、搜索、RSS 全都有;
- 全程 0 元——没有服务器,没有付费订阅。
这篇文章把我这套东西从零到一怎么搭起来的讲清楚,希望你能照着复刻一个。
一、总体架构
先上全景图,后面每一步都是在填这张图的一块:
1 | ┌────────────────────────────────────────────┐ |
核心思路就三句话:
- Hexo 负责把 Markdown 变成静态 HTML,本地不需要常驻任何东西;
- GitHub 私有仓库存放源码,它是唯一事实来源——后台发布文章,本质上也是往这个仓库写文件;
- Cloudflare 免费托管 + 免费后端:Pages 负责静态文件和自动构建,Pages Functions 提供动态接口,R2 当图床。
二、成本清单:到底花了多少钱
| 组件 | 用的什么 | 花费 |
|---|---|---|
| 静态站点生成器 | Hexo + Butterfly 主题 | ¥0(开源) |
| 代码托管 | GitHub 私有仓库 | ¥0(Free 套餐够用) |
| 托管 + CDN + HTTPS | Cloudflare Pages | ¥0(免费档) |
| 动态后端 | Cloudflare Pages Functions | ¥0(免费档,每天 10 万次请求) |
| 图床 | Cloudflare R2 | ¥0(免费 10 GB,流量不收费) |
| 域名 | dpdns.org 免费二级域名 | ¥0 |
| 评论系统 | giscus(GitHub Discussions) | ¥0 |
唯一可能产生的花费:你想要一个自己买的域名(一年几十块)。我用的 dpdns.org 免费域名,暂时一分钱没花。
免费额度都是「对个人博客严重过剩」级别:Pages 每月 500 次构建、R2 存 10 GB 图片、Functions 每天 10 万次请求。具体数字以 Cloudflare 官网为准,但对你我这种量级的博客,放心用。
三、第一步:本地把 Hexo 站跑起来
这步网上教程最多,我只说三个容易踩的点。
1. 主题用 submodule 管理,永远别直接改主题文件。
1 | git submodule add https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly |
Butterfly 的所有定制都写在站点根目录的 _config.butterfly.yml 覆盖文件里。这样以后主题升级只是更新一下 submodule 指针,你的定制一行都不会丢。我后来把主题 fork 了一份做深度二开,也只是把 submodule 指向自己的 fork,原则不变。
2. 配色之类的 Stylus 配置改完要 hexo clean。
这类配置会被编译缓存进 db.json,不 clean 你会遇到「配置明明改了颜色就是不变」,怀疑人生的经典来源。
3. _posts 里的文件名就是永久链接的一部分。
本站永久链接格式是 :year/:month/:day/:title/,文件名里的中文会直接出现在 URL 里。介意外文中文 URL 的话,可以用 hexo-permalink-slug 之类的插件,或者文件名用英文、标题写中文。
四、第二步:推上 GitHub,让 Cloudflare 帮你构建
- 在 GitHub 建一个私有仓库,把整个 Hexo 站推上去。私有仓 + 免费额度完全够,草稿和没公开的折腾不怕被人看到。
- 到 Cloudflare 控制台 → Workers & Pages → 创建 Pages 项目 → 连接这个 GitHub 仓库。
- 构建配置只需要两行:
1 | 构建命令: npm run build # 即 hexo generate |
之后每次 git push,Cloudflare 自动拉代码、装依赖、构建、发布到全球 CDN,全程一分钟以内。HTTPS 证书自动配好,什么都不用管。
域名:Pages 项目默认送一个 *.pages.dev 域名,嫌长的话可以在 Cloudflare 里绑自定义域。我是用 DigitalPlat 的免费域名服务(dpdns.org)申请的二级域名,解析托管在 Cloudflare,也是免费。
到这一步,你已经拥有一个免费、全球加速、自动部署的静态博客了。接下来的部分才是「别人不知道」的。
五、第三步:图床——Cloudflare R2
为什么需要图床? 文章里的截图如果直接放仓库里,仓库会越来越肥,构建越来越慢,而且 Markdown 里的相对路径离开本地就失效。正确姿势是图片放对象存储,Markdown 里只写外链。
市面上免费图床不少(imgbb、sm.ms……),但普遍的问题是:域名不可控(哪天挂了或换域名,全站图片跟着遭殃)、额度小、不知道哪天就政策收缩。所以我选了 Cloudflare R2:
- 免费 10 GB 存储,流出流量免费(这点是 R2 最大的杀手锏,别的云对象存储流量费是大头);
- 可以绑自己的域名,图片链接永远在自己的域名下,可控;
- 和 Pages 同在 Cloudflare,后台接口直接用
env.IMAGES_BUCKET访问,不用签什么临时凭证。
R2 开通后:创建一个桶 → 在设置里绑定一个自定义域(比如我的 blogimg.kkkkikun.dpdns.org)→ 桶里的对象就能通过这个域名直接访问了。
我的上传接口做的事很简单:收图片 → 校验类型 → 按 images/年/月/时间戳-文件名 存进桶 → 返回外链。有两个细节值得抄:
- 只收 png/jpeg/gif/webp,拒绝 SVG。SVG 能内嵌脚本,允许上传等于在图床域名上开了一个存储型 XSS 的口子,而图床域和主站同属一个大站范围,不能不防;
- 按年/月分目录,后台提供图片列表和删除,清理过期截图不用进控制台。
写作体验上是:后台编辑器里 Ctrl+V 粘贴截图 → 自动传 R2 → 编辑器里插入外链。发图文文章从此不需要「先开图床网站 → 上传 → 复制链接 → 粘贴」四连。
六、第四步:在线发布后台(本文最有意思的部分)
很多人以为静态博客注定「只能本地发布」。其实 Cloudflare Pages 自带一个容易被忽略的能力:Pages Functions——在仓库里放一个 functions/ 目录,它就是一个跑在 Cloudflare 边缘的 serverless 后端,免费额度每天 10 万次请求,对个人后台绰绰有余。
于是静态站就有了后端。我的后台是这么工作的:
1. 登录与鉴权。
后台就一个口令,存在 Cloudflare Pages 的环境变量里(不进代码仓库)。登录成功后发一个 SHA-256 派生的会话 cookie,有效期 7 天;/api/* 用一个中间件统一校验,所有接口不用各自写鉴权。口令未配置时所有接口直接锁死——安全默认,防止裸奔。
2. 发布文章的本质:往 GitHub 仓库写一个文件。
这是整套设计里我最得意的一招。后台点「发布」,Function 做的事是:
1 | 组装 front matter(title/date/tags/categories/cover/description) |
也就是说后台不需要任何数据库——GitHub 仓库就是数据库,git 历史就是文章的修改记录,永远可回滚。文章的增删改查全部是对同一个 GitHub API 的封装,我还做了草稿目录(_drafts/):写一半的文章存草稿,不触发发布,哪天写完一键转正。
这里有个我真实踩过的坑:生成文章日期别用 toISOString()。它是 UTC 时间,早上八点前发文,日期会被算成前一天,permalink 直接错位。要用 toLocaleString 转成上海时区再格式化。
3. 编辑器。
后台编辑器用的是 Milkdown Crepe,Notion 风格的所见即所得 Markdown 编辑器,用 esbuild 打包成自包含的单文件产物随仓库提交,部署时不需要额外构建步骤。粘贴图片自动走上面的 R2 上传接口。
到这一步,写作体验已经和掘金/知乎这类在线平台没差别了:打开网页 → 登录 → 写 → 发布。但它发出来的是你自己域名下的、纯静态的、没有广告和你完全掌控数据的文章。
七、第五步:评论、搜索、RSS 这些「动态功能」
剩下的动态能力,全都有成熟的免费方案:
- 评论:giscus。 借 GitHub Discussions 当评论存储,访客用 GitHub 账号登录即可评论,零服务器、零成本,数据还归你自己(我单独建了个公开仓库存评论,和源码仓解耦)。国内访客加载可能略慢,开 lazyload 后不影响首屏。
- 站内搜索:hexo-generator-searchdb。 构建时生成一个索引 JSON,前端纯静态查询,不需要任何搜索服务。
- RSS:hexo-generator-feed;sitemap:hexo-generator-sitemap。都是装上就完事的插件,分别喂给 RSS 阅读器和搜索引擎。
八、这套东西的边界(诚实说)
免费方案不是没有代价,有几个点你要心里有数:
- 免费额度是「条款」不是「合同」。Cloudflare 免费档对个人博客完全够用,但如果哪天某篇文章爆了,构建次数、请求量都要留个心眼;
- 后台是给「自己」用的,不是给「很多人」用的。它没有多用户、没有审批流,防的是陌生人和脚本,不是恶意 insider;
- 域名是软肋。免费域名理论上有政策风险,重要内容记得定期
git pull留本地备份——反正源码在 git 里,重建整个博客也就十分钟。
九、总结
| 你以为需要 | 实际需要 |
|---|---|
| 一台服务器 | 不需要 |
| 数据库 | 不需要 |
| 图床会员 | 不需要 |
| 每年几百块 | 0 元 |
| 本地写稿 + 命令行发布 | 打开网页,写完点发布 |
整套东西的技术关键词就是:Hexo + GitHub 私有仓库 + Cloudflare Pages / Functions / R2 + giscus。没有什么高深的东西,更多是「知道这些免费件可以这么拼起来」——希望这篇能帮你把拼图凑齐。
如果你照着搭的过程中卡在哪一步,或者想看我某个环节的具体实现,欢迎在评论区(GitHub Discussions)留言交流。