从零搭建个人博客:Astro + Cloudflare Pages
2026 年 5 月,花了一天时间把这个博客搭了起来。当时做的那串决定,现在回头看都还成立;但博客本身已经和最开始长得完全不一样了。
为什么选这套方案
最开始考虑过 WordPress 和 Ghost,但它们需要一直运行在服务器上,吃内存、要维护。
最终选了 Astro + Cloudflare Pages:
- Astro:静态站生成器,把 Markdown 文章编译成纯 HTML,不需要服务器运行时
- Cloudflare Pages:免费托管静态站,全球 CDN 加速,
git push自动发布 - Decap CMS:浏览器里直接写文章的后台,不用每次开命令行
整个链路:写文章 → 保存 → GitHub → CF Pages 自动构建发布。服务器全程不参与。
从模板起步
起点是 astro-nano,一个极简风格的 Astro 主题:
git clone https://github.com/markhorn-dev/astro-nano blog
cd blog
npm install
npm run dev # 本地预览
改 src/consts.ts 里的站名、简介和社交链接,推到 GitHub,再到 Cloudflare Dashboard 建一个 Pages 项目(Build command 是 npm run build、Output directory 是 dist),绑定自己的域名,博客就上线了。整套方案完全免费,CF Pages 免费层对个人博客够用。
后来它长成了这样
模板只是起点。之后几个月它一直在变:
视觉:shadcn 的默认灰白和 Inter/Lora 换掉了,现在是暖纸底配等宽骨架,字体走 @fontsource 自托管;文章页的代码块有语法高亮,注释是松木绿。
内容结构:多了 projects 项目索引,还有一个二次元板块——番剧、角色、收藏,风格和主站故意不一样,贴纸本那种。
后台:Decap CMS 接的是自己写的 OAuth 代理(GitHub 登录),Client Secret 只存在 CF Pages 的环境变量里。
安全:CSP 在 Cloudflare Pages Functions 里按路径区分设置,前台页面的内联脚本靠 hash 白名单;文章内容过 sanitize。
协作:写这个博客本身就是双模型工作流跑出来的——一个 session 管方向决策,一个管实现,中间用两个 markdown 文件交接。
这些是后话。搭站的当天,重要的是把「为什么选这套」想清楚,然后它自然会往自己该有的样子长。
写文章
文章放在 src/content/blog/ 下,每篇一个文件夹,头部一段 frontmatter:
---
title: "文章标题"
description: "简介"
date: 2026-05-19
draft: false
---
正文内容...
写完 git push,Cloudflare Pages 一分钟内自动发布。