我的博客”缓存”上线了,地址是 https://cache.xucong.com 。这篇文章记录它用了哪些平台、具备哪些功能、以及平时怎么在上面写作和部署。想搭一个类似个人博客的话,可以把它当作一份参考。
技术栈与平台
- Astro 7 + AstroPaper 6:静态站点生成器加初始主题。选它的原因:静态输出适合 Cloudflare Pages;Markdown 是一等公民;自带 RSS、标签、归档、搜索、深浅色主题和 SEO 基础;主题代码完全在仓库里,可以持续删减和修改。
- Markdown:所有文章就是
src/content/articles/目录下的.md文件。 - pnpm:包管理器。
- GitHub(私有仓库):同时承担三个角色——保存站点和文章的版本历史、运行 CI 校验(lint、格式、Astro 构建)、接收 Agent/API 请求并触发自动发文流程。
- GitHub Actions:两个工作流,一个负责接收文章草稿请求,一个负责构建并部署到 Cloudflare。
- Cloudflare Pages:负责发布构建产物,并通过 Cloudflare DNS 绑定
cache.xucong.com。 - 域名:复用已有的
xucong.com,没有另买新域名,在cache.xucong.com和huancun.xucong.com之间选了更短更自然的那个。
博客的功能
第一版完成的功能包括:RSS 订阅、搜索、标签、归档、深浅色主题、SEO 基础、中文语言和日期格式、自定义 favicon 和默认 Open Graph 图片,以及偏纸张感、绿色强调色的视觉风格。
上线之后我做了一轮精简:删掉了首页的大段自我介绍和宣传文案、RSS 图标旁的冗余说明、口号式标签、“关于”页面和导航入口,以及第一篇解释博客名字的文章。公开站点目前刻意保持空白,从零开始积累内容。
怎么写文章
写文章有两种方式,都离不开 Markdown。
一种是直接写:在 src/content/articles 下新建一个 .md 文件,开头标记 draft: true,本地跑一遍 lint、格式检查和构建,确认没问题后把 draft 改成 false 提交,剩下的交给 GitHub Actions 自动构建部署。仓库里还放了个 scripts/new-post.mjs 小脚本,方便快速生成新文章模板。
另一种是让 Agent 帮忙写:仓库的发文工作流支持 API 触发(repository_dispatch 事件,事件名 publish-post),传标题、slug、摘要、标签、正文五个字段,工作流会把内容整理成 Markdown 提交到 main 分支。我也在 Hermes 里配了一个 Skill,可以创建草稿、列出文章、读取文章、发布草稿,写起来和直接在仓库里建文件差不多。
无论哪种方式,新文章都会先以草稿状态进入仓库,不会出现在公开页面上,等我审核通过后才会发布。
部署是怎么自动化的
最初想用 Cloudflare 官方 MCP 完成 Pages 项目、域名和 DNS 配置,但它的 OAuth 授权码流程要求回调到服务器本地地址,而浏览器在另一台机器上,两边对不上;Cloudflare 又不支持设备授权流,最终放弃了这个方案。
改用更稳定的方式:Cloudflare API Token 只保存在 GitHub Actions Secrets 中,仅授予 Pages 写入和域名 DNS 写入权限,仓库代码和任何 Agent 环境都不保存明文。部署流程由 GitHub Actions 幂等地完成:创建或复用 Pages 项目 → 安装依赖并构建 Astro → 用 Wrangler 部署产物 → 关联 cache.xucong.com → 创建或修正对应 CNAME。
第一次真实部署踩过一个坑:项目里有 pnpm-workspace.yaml,cloudflare/wrangler-action 试图在 workspace 根目录临时执行 pnpm add,触发了 ERR_PNPM_ADDING_TO_ROOT。修复方式是把 Wrangler 明确加入项目的 devDependencies 并锁定版本,让 Action 直接使用项目内已安装的 Wrangler。
发一篇文章的完整流程
写或生成草稿 → 审阅 → 把 draft 改成 false → 自动部署。整个流程都基于 Git 和 GitHub Actions,不需要碰 Cloudflare 后台,提交到 main 之后部署自动完成。
这篇文章本身,也是按这个流程发出来的。