用 GitHub + Cloudflare 搭建自己的 Blog 平台

为什么想做这个 Blog

一直想做一个自己的 Blog 平台。

最早的想法很简单:希望有一个属于自己的云端空间,用来学习云端知识,记录学习内容,也方便在不同设备上随时打开、快速查阅和对外展示。

但这个想法之前一直没有真正开始。原因也很现实:自己搭云服务听起来就意味着服务器、运维、域名、部署、安全、备份和持续费用。对个人学习项目来说,如果一开始就要持续付费和长期维护,很容易先被成本劝退。

后来,AI 编程工具逐渐成熟。它把很多原来需要长时间搜索、试错和反复调试的工作,变成了可以快速验证的小步迭代。试错成本明显降低之后,这个 Blog 项目才真正开始推进。

项目起因,是搜索资料时看到别人用 GitHub Pages 搭建个人网站。GitHub Pages 给了一个很好的启发:个人 Blog 不一定要从买服务器开始,也可以先从静态网页开始。于是我先从 GitHub Pages 的思路出发,尝试搭建一个低成本、可维护、可持续迭代的个人 Blog。

随着和 AI 一起不断深入方案,最后发现 GitHub + Cloudflare 更适合这个目标:GitHub 负责代码和版本管理,Cloudflare 负责静态网站托管、域名、CDN、HTTPS,以及后续的边缘函数、数据库和 AI 扩展能力。

所以这篇笔记记录的不是一个“一次性建站教程”,而是一个个人 Blog 从静态网页逐步演进成云端内容平台的过程。

当前成品

当前正式访问地址:

现在它已经不只是一个纯静态 Blog。它包含:

  • Markdown 文章发布。
  • 首页、文章页、标签、分类、归档。
  • 自定义域名和 HTTPS。
  • 评论系统。
  • 邮箱订阅、退订确认和文章更新通知。
  • 友链申请、AI 审核和后台人工管理。
  • 管理后台。
  • 站内搜索和 AI 问答入口。
  • 访问统计、订阅人数、互动数据。
  • 社交链接入口。
  • Cyber Matrix 矩阵雨背景、头像动画和首页视觉动效。

这也是我对它的新定位:

用低成本云服务,搭一个可持续迭代的个人内容平台。

实际效果截图

下面这些截图来自本地预览环境,用来展示当前 Blog 的公开页面效果。截图只覆盖公开页面和 Admin 登录页,不展示后台数据、Cloudflare 控制台、邮箱、token 或数据库敏感字段。

首页效果

Blog 首页:标题标语、矩阵雨背景和右侧信息卡

首页主要展示站点名称、标语、矩阵雨背景和右侧信息入口。首页可以更强调氛围感,因为它承担的是第一眼印象。

文章阅读页

文章页:静态文章和右侧栏阅读体验

文章页更重视阅读体验。背景动效需要降低存在感,避免干扰正文。

友链页面

友链页:自动提交、AI 审核和右侧栏

友链页从静态说明扩展成了可提交、可审核、可自动收录的互动入口。

AI 入口

AI站内搜索页

正常关键词站内搜索

AI站内搜索页

未知关键词站内搜索

AI回复页

正常关键词AI回复

AI回复页

未知关键词AI搜索

AI 入口放在导航栏中,目标是把站内搜索逐步升级为“用问题查文章”的方式。

Admin 后台

下面这些截图来自测试环境后台,只使用示例评论、示例友链、示例订阅和汇总统计,不展示密码、token、邮箱密钥或 Cloudflare 控制台账号信息。

Blog 后台登录界面

登录页只保留管理员入口,口令在 Cloudflare 环境变量中配置,页面本身不保存明文密码。

Blog 后台站点概览

概览页把访问分析、待处理事项和热门文章放在一起,方便第一眼确认站点状态。

Blog 后台评论管理

评论管理按文章归属展示评论、回复、审核状态和删除入口,适合处理垃圾评论和人工回复。

Blog 后台友链管理

友链管理保留人工审核入口。自动识别失败或需要人工确认的网站,可以在后台补充名称、描述和头像。

Blog 后台订阅用户

订阅页用来查看订阅状态、退订状态和通知失败情况。

Blog 后台邮件通知记录

通知记录独立成页,便于检查文章更新邮件是否发送成功。

Blog 后台文章数据与单篇查询

文章数据页展示浏览、点赞、评论和近 7 天趋势,也支持按路径查询单篇文章。

Blog 后台访问分析

Cloudflare 访问分析主要用于查看近 24 小时或近 7 天请求、访客和带宽变化。

Git Notes 文章管理

早期 PagesCMS 文章列表

项目早期使用 PagesCMS 直接编辑 Blog 仓库文章。随着内容结构稳定,文章已经迁移到独立私有 Notes 仓库,按 Tech、Life、Explore、Collection、Notes 五个目录管理。

每篇 Markdown 同时保存标题、发布时间、永久链接、TDK、标签、内容类型和发布权限。Blog 只读取 visibility: public 的内容,图片也随 Notes 仓库版本化管理。

最终选型

当前 Blog 使用的核心组合是:

  • GitHub:分别保存 Blog 源码、Notes 内容和完整版本历史。
  • Git Notes 同步:验证公开文章、生成分类与更新时间,并同步到 Blog test。
  • PagesCMS:只管理关于页、友链说明等 Blog 自有页面。
  • Hexo:把 Markdown 文章生成静态网页。
  • Butterfly:作为 Hexo 主题,提供基础博客布局和阅读体验。
  • Cloudflare Pages:托管静态网站并自动部署。
  • Cloudflare DNS:管理域名解析和 HTTPS。
  • Cloudflare D1:保存评论、友链、订阅、统计等轻量数据。
  • Cloudflare Pages Functions:给静态站点增加 API。
  • Cloudflare Workers AI / Vectorize:预留和承载 AI 搜索、问答、向量检索能力。
  • Resend:发送订阅、退订、评论和文章更新邮件。
  • Gemini / Tavily:辅助友链审核与联网搜索证据。

从结果看,这个组合很适合个人站:成本低、部署简单、扩展空间足够,而且每一步都能独立验证。

GitHub 是什么,在这个项目里做什么

GitHub 是代码托管平台。它最重要的能力不是“存代码”这么简单,而是提供版本管理、分支协作、提交记录和远程备份。

在这个 Blog 项目中,GitHub 主要承担这些职责:

  1. 保存 Blog 源码。
  2. 保存 Markdown 文章。
  3. 记录每一次修改历史。
  4. 使用分支区分测试版本和正式版本。
  5. 让 Cloudflare Pages 可以从 GitHub 自动拉取代码并构建网站。

当前项目使用两个主要分支:

  • test:测试分支,用来触发 Cloudflare Pages Preview 部署。
  • main:正式分支,用来触发生产环境部署。

这个流程的好处是:文章、样式、配置和功能改动都先进入测试环境确认,确认没问题后再合并到正式环境。

GitHub Pages 是什么,为什么最后没有只用它

GitHub Pages 是 GitHub 提供的静态网站托管服务。很多个人主页、文档站和简单 Blog 都可以直接放在 GitHub Pages 上。

它的优点是:

  • 免费。
  • 和 GitHub 仓库天然集成。
  • 很适合纯静态页面。
  • 上手成本低。

这个项目最初也是受 GitHub Pages 启发。但继续深入后,发现项目需求不只是“把静态页面放出来”。后续还希望有:

  • 自定义域名和 HTTPS。
  • 更强的 CDN 和缓存能力。
  • 评论、订阅、友链、访问统计等轻量动态功能。
  • 边缘函数能力。
  • 后续 AI 搜索、问答、数据索引等扩展空间。

所以最终选择 GitHub + Cloudflare Pages:GitHub 继续负责源码和分支,Cloudflare 负责部署和云端能力。

Hexo 是什么

Hexo 是一个静态博客生成器。它可以把 Markdown 文件转换成完整的静态网站。

GitHub 地址:

官网:

Hexo 的核心能力包括:

  • 使用 Markdown 写文章。
  • 自动生成文章页、首页、标签页、分类页和归档页。
  • 支持主题系统。
  • 支持本地预览。
  • 构建后输出纯静态文件,方便部署到任何静态托管平台。

在这个 Blog 中,Hexo 负责把文章生成最终网页。平时只需要写 Markdown,构建时 Hexo 会生成 HTML、CSS、JS、文章列表和搜索索引。

Butterfly 是什么

Butterfly 是 Hexo 生态里一个常用的博客主题。它提供了完整的博客界面和阅读体验。

GitHub 地址:

文档:

Butterfly 主要提供:

  • 响应式页面布局。
  • 首页、文章页、归档页、分类页、标签页样式。
  • 代码块展示。
  • 目录导航。
  • 文章卡片。
  • 搜索入口。
  • 页面视觉和交互效果。

在这个 Blog 中,Butterfly 负责基础外观和阅读体验。我们使用它作为主题底座,而不是从零写前端页面。

这样做的好处是:先把精力放在内容、部署和云端能力上,页面基础体验直接站在成熟主题之上。

Cloudflare 是什么,在这个项目里做什么

Cloudflare 是一套云网络和边缘计算平台。它最常见的能力包括:DNS、CDN、HTTPS、网站托管、边缘函数、数据库和安全防护。

在这个 Blog 项目里,Cloudflare 承担这些职责:

  1. 托管静态网站:Cloudflare Pages。
  2. 绑定自定义域名:Cloudflare DNS。
  3. 自动提供 HTTPS 证书。
  4. 使用 CDN 加速访问。
  5. 使用 Pages Functions 提供 API。
  6. 使用 D1 保存轻量数据。
  7. 使用 Workers AI / Vectorize 支撑 AI 搜索扩展。
  8. 为后续更多边缘能力留出空间。

Cloudflare 对个人站最友好的地方,是很多能力都有免费额度。对于一个低流量个人 Blog 来说,Pages、Functions、D1、DNS 和 HTTPS 已经可以覆盖大部分需求。

Cloudflare 相关扩展可以单独看这篇:

域名绑定流程

域名绑定的目标是让用户访问自己的域名,而不是默认的 Cloudflare Pages 域名。

当前正式域名是:

1
blog.fsj.dpdns.org

大致流程如下:

  1. 在 Cloudflare 中接入 fsj.dpdns.org 这个域名。
  2. 在 Cloudflare Pages 中打开 Blog 项目。
  3. 添加自定义域名 blog.fsj.dpdns.org。
  4. 在 Cloudflare DNS 中添加 CNAME 记录。
  5. 让 blog.fsj.dpdns.org 指向 Cloudflare Pages 默认域名。
  6. 等待 Cloudflare 完成域名验证和 HTTPS 证书配置。
  7. 访问 https://blog.fsj.dpdns.org/ 验证页面是否正常打开。

当前没有强制把裸域名跳转到 Blog。重点只放在:

这种做法更简单,也避免一开始就把根域名用途固定死。以后如果根域名要做导航页、个人主页或其它服务,也可以继续扩展。

从静态 Blog 到可交互平台

最开始的目标只是把文章发布出去。但随着使用深入,静态 Blog 的边界很快出现:读者无法评论,无法订阅更新,友链需要人工改代码,访问统计也没有地方保存。

所以后续在静态站基础上补了几类动态能力。

评论系统

评论系统由前端组件、Pages Functions 和 D1 组成。

基本逻辑是:

  1. 文章页显示评论区。
  2. 用户提交评论。
  3. API 接收并写入 D1。
  4. AI 审核或后台人工审核。
  5. 审核通过后在文章页展示。
  6. 如果开启回复通知,则使用当前浏览器记住的订阅邮箱发送提醒。

这样既保留了静态站部署简单的优点,也让文章具备基础互动能力。

邮箱订阅

订阅功能用于记录读者邮箱,并在文章更新时发送提醒。

当前订阅流程包含:

  • 浏览器本地记住订阅状态。
  • 已订阅时显示退订、退出和编辑名称入口。
  • 重复订阅时识别已有邮箱,并显示欢迎回来。
  • 退订需要邮件二次确认。
  • 文章更新时可以触发更新通知邮件。
  • 订阅人数可以在页面侧边栏展示。

邮件发送由 Resend 负责,发件域名走自己的域名体系。这个部分更详细的记录放在私人 Email 搭建笔记里。

友链系统

友链最初可以手动展示,后来改成自动申请和后台管理。

当前逻辑是:

  1. 用户提交站点链接和名称。
  2. 系统先访问链接,访问失败直接返回失败。
  3. 如果能访问,再进入 AI 审核。
  4. Tavily 提供联网搜索证据。
  5. Gemini 或 Cloudflare AI 辅助判断站点是否正常。
  6. AI 通过则自动收录。
  7. AI 不确定则进入后台人工审核。
  8. 管理后台可以手动新增、批准、拒绝或删除友链。

为了避免空头像影响视觉,默认友链头像改成纯色背景和“友”字。没有描述时,默认使用“名称 + blog”的形式。

管理后台

后来单独增加了 Admin 管理界面,用来管理动态数据。

它主要用于:

  • 查看统计摘要。
  • 管理评论。
  • 回复评论。
  • 审核友链。
  • 人工新增友链。
  • 管理订阅用户。
  • 查看文章更新通知发送记录。

后台登录做了基础防护:连续错误和滚动错误都会触发锁定,降低暴力尝试风险。登录页也做了独立视觉设计,而不是简单表单。

站内搜索和 AI 问答

站内搜索从传统搜索入口扩展为导航栏里的 AI 入口。

它的目标不是替代文章列表,而是让读者可以用问题的方式查找内容:

  • 普通站内搜索:更适合关键词定位。
  • Cloudflare AI 搜索:更适合语义查询。
  • AI 问答:更适合根据已有文章做总结式回答。

当前这个能力依赖 Cloudflare Workers AI 和 Vectorize。它更像后续知识库能力的起点。

视觉动效

视觉上也做了一些定制:

  • 首页标语改为“与 AI 协作,快速验证每一个新想法”。
  • 首页和导航区域增加更统一的科技风格。
  • 使用 Cyber Matrix 粒子/矩阵雨作为背景。
  • 首页可以更明显地展示动效,文章页则降低强度,避免影响阅读。
  • 头像从静态图变成带字母切换和光点环绕的动效。
  • 订阅、抖音、知乎、B 站等入口统一成一组社交按钮。
  • 右侧公告栏改成更像推荐入口的滚动列表。

动效的原则是:首页可以更有氛围,文章页必须让阅读优先。

当前架构图

可以把当前 Blog 理解成四层:

1
2
3
4
5
6
7
8
9
10
11
写作层
GitHub 私有 Notes 仓库
↓
生成层
Git Notes 同步 + Hexo + Butterfly
↓
部署层
GitHub -> Cloudflare Pages
↓
动态能力层
Pages Functions + D1 + Resend + Workers AI + Vectorize

这套结构的好处是:核心内容仍然是静态生成,稳定、便宜、好缓存;互动能力通过 Cloudflare 的边缘能力补上,不需要自己维护服务器。

本地开发流程

日常写文章时,主要流程是:

  1. 在 Notes 仓库修改 Markdown 和相关图片。
  2. 运行内容校验并提交到 notes/test 或 notes/main。
  3. Notes push 事件触发 Blog 工作流,生成文章、TDK、分类、更新时间和图片。
  4. notes/test 只同步 blog/test,部署 Cloudflare Preview。
  5. notes/main 只同步 blog/main,部署 Cloudflare Production。
  6. Blog 框架自身 push 只构建已提交的内容,不重新读取 Notes。
  7. 如果涉及 API / D1,再补充 Pages 本地或云端验证。

常见命令思路:

1
2
3
npm run serve
npm run build
npm run dev:pages

其中 npm run serve 只适合看纯静态页面;如果改了评论、订阅、友链、统计、AI 搜索等功能,就要走 Pages + D1 的本地预览或云端测试。

Git Notes 内容管理

早期 Blog 内容工作流

早期内容同时经过 Joplin、PagesCMS 和 Blog 仓库,修改入口过多,容易出现字段不一致和内容被下一次同步覆盖的问题。

现在使用独立私有仓库 feng-shijie/notes 作为文章唯一源头:

  • 五个一级目录决定稳定大分类。
  • Frontmatter 保存标题、TDK、标签、内容类型和发布权限。
  • assets/<文章文件名>/ 保存文章图片。
  • Git commit 记录修改历史,并提供文章更新时间。
  • 仓库校验器阻止无效字段、重复永久链接和缺失图片进入发布流程。

同步流程:

1
2
notes/test push  -> blog/test  -> Cloudflare Preview
notes/main push -> blog/main -> Cloudflare Production

两个分支独立对应,不自动互相合并。Blog 工作流使用只读 Deploy Key 获取事件指定的 Notes commit;同步器只处理 visibility: public,并通过 manifest 限制可覆盖和删除的文件范围。

PagesCMS 的当前职责

PagesCMS 仍可用于轻量编辑,但不再直接修改 Blog 文章。它只管理:

  • 关于页。
  • 友链说明页。
  • source/img/uploads/ 中的 Blog 自有图片。

source/_posts/ 和 source/img/notes/ 是同步生成目录,直接修改会在下一次 Notes 同步时被覆盖。

发布流程

这个 Blog 的发布流程强调“先测试,再正式发布”。

推荐流程:

  1. 本地完成文章或功能修改。
  2. 本地构建通过。
  3. 推送到 test 分支。
  4. 等待 Cloudflare Pages Preview 部署成功。
  5. 打开测试地址检查页面和功能。
  6. 确认无误后合并到 main。
  7. Cloudflare Pages 自动发布正式站点。
  8. 访问正式域名做最终确认。

这种方式比直接推正式环境更稳,也更适合 AI 辅助开发。AI 可以快速生成修改,但仍然需要通过测试环境确认结果。

用到的开源项目和文档

核心开源项目:

参考过的视觉灵感:

官方文档:

当前站点:

成本和限制

这套方案最大的优点是低成本。GitHub、Cloudflare Pages、Cloudflare DNS、D1、Workers AI、Vectorize 和 Resend 都有免费或低成本入口。对于个人 Blog 来说,这已经足够支撑早期使用。

但它也有边界:

  • 免费额度不是无限资源。
  • 邮件送达率需要慢慢养域名信誉。
  • D1 适合轻量数据,不适合复杂后台系统。
  • AI 搜索需要索引质量和提示词持续优化。
  • 动态背景不能影响文章阅读和低性能设备体验。
  • 自动审核不能完全替代人工判断。

所以当前策略是:核心内容保持静态,动态能力只做必要增强;能用简单方案解决,就不急着引入复杂架构。

这次搭建的收获

这次 Blog 搭建最大的变化,不只是做出了一个网站,而是把“个人云端平台”这件事拆成了可迭代的小步骤:

  • 先用 GitHub 保存内容和代码。
  • 再用 Hexo 生成静态 Blog。
  • 再用 Butterfly 快速获得可用的阅读体验。
  • 再用 Cloudflare Pages 发布到公网。
  • 再绑定自己的域名。
  • 再逐步加入评论、订阅、友链、后台、统计、搜索和 AI 能力。

以前觉得“搭一个自己的云端平台”像是一个很大的项目;现在借助 AI 编程工具,可以把它变成一连串可以验证的小任务。

这也是这个 Blog 的初心:用低成本的方式,搭一个自己的学习记录入口;既能沉淀内容,也能不断练习云端、前端、部署、域名、边缘函数和数据服务这些真实技术。

会持续更新,慢,但不停。