Hexo 博客部署到 Cloudflare Pages 完整流程
这篇文章记录一次将 Hexo 博客源码托管到 GitHub,并通过 Cloudflare Pages 自动构建、部署、绑定自定义域名的完整过程。
写这篇文章的背景也很简单:之前博客一直部署在阿里云服务器上,但服务器到期后,如果只是为了放一个静态博客,继续续费一台云服务器有点浪费。Hexo 本身生成的就是静态文件,而 Cloudflare Pages 免费额度已经足够个人博客使用,还自带 HTTPS、CDN、DNS 和基础安全防护,所以这次就把博客迁移到了 Cloudflare Pages。
最终效果是:每次本地写完文章后,只需要把代码推送到 GitHub,Cloudflare Pages 就会自动拉取代码、执行 Hexo 构建,并把博客发布到自己的域名上。
1. 整体原理
整个流程可以理解为:
|
其中:
- GitHub 负责保存 Hexo 博客源码。
- Cloudflare Pages 负责自动构建和托管网站。
- DNS 负责把自己的域名指向 Cloudflare Pages。
- Cloudflare 负责 HTTPS、CDN 加速和基础安全防护。
2. 准备 Hexo 博客仓库
Hexo 项目中通常会包含这些文件和目录:
|
其中 source/_posts/ 保存博客文章,themes/ 保存主题,_config.yml 是 Hexo 的主配置文件。
建议 .gitignore 中排除这些内容:
|
public/ 是 Hexo 构建后的产物,不需要提交到 GitHub。Cloudflare Pages 会在云端自动生成它。
3. 处理主题 submodule 问题
部署时最先遇到的问题是 Cloudflare Pages 报错:
|
这个错误说明 Cloudflare 在拉取 GitHub 仓库时,尝试更新 Git submodule,但仓库里的子模块配置不完整或不可访问。
可以通过下面的命令检查:
|
如果看到类似:
|
说明主题目录仍然被 Git 当成 submodule。
解决方法是把主题改成普通文件夹:
|
如果执行 git add themes/yilia 时出现:
|
说明主题目录内部还有自己的 .git 文件夹。需要删除主题内部的 .git:
|
注意:删除的是主题目录内部的 .git,不是博客项目根目录的 .git。
4. 修复依赖安装问题
解决 submodule 后,Cloudflare 进入依赖安装阶段,又出现了错误:
|
日志中关键部分是:
|
原因是 package.json 中的 hexo-asset-image 依赖使用了 GitHub 地址,Cloudflare 构建时被解析成了 SSH 地址:
|
Cloudflare 构建环境没有我的 GitHub SSH 权限,所以无法拉取这个依赖。
一开始我尝试把它改成 npm 版本:
|
这个版本虽然可以安装成功,但后面发现它会把文章图片路径处理错。我的域名是:
|
npm 版本的 hexo-asset-image 会把 .xyz 误识别成路径的一部分,导致生成出来的图片地址变成:
|
而正确的文章图片路径应该类似:
|
所以最终采用的方案是:继续使用 GitHub 版本的 hexo-asset-image,但把依赖地址写成明确的 HTTPS Git 地址,避免 Cloudflare/Yarn 把它解析成 SSH:
|
同时删除 yarn.lock,统一使用 npm 安装依赖:
|
这样 Cloudflare Pages 会通过 HTTPS 拉取 GitHub 上的插件版本,不需要 SSH 权限,也能保留之前博客文章的图片路径处理方式,避免大面积修改旧文章。
5. 创建 Cloudflare Pages 项目
进入 Cloudflare 控制台:
|
如果进入的是 Worker 创建页面,需要点击底部:
|

然后选择:
|

选择自己的 GitHub 仓库,例如:
|
6. 配置构建命令
Cloudflare Pages 中 Hexo 的关键配置如下:
|
如果页面中出现必填的:
|
说明进入了 Workers 部署流程,不是 Pages。Hexo 博客不需要填写 npx wrangler deploy。
Pages 只需要构建出 public 目录,Cloudflare 会自动发布这个目录。
建议在环境变量中添加:
|

7. 部署成功
配置完成后,Cloudflare Pages 会自动执行:
|
部署成功后会得到一个默认域名,例如:
|

之后每次更新博客,只需要:
|
Cloudflare Pages 会自动重新构建和发布。
8. 接入自定义域名
我的域名是:
|
首先在 Cloudflare 中添加站点:
|
输入域名后选择免费套餐:
|

9. 配置 DNS 记录
因为我希望主域名直接访问博客,所以将原来指向旧服务器的 A 记录删除:
|
然后新增两条 CNAME:
|
代理状态保持:
|
TTL 保持:
|

10. 修改域名的 Nameserver
Cloudflare 会给出两个 nameserver,例如:
|
需要到域名注册商后台,将原来的 DNS 服务器改成 Cloudflare 提供的这两个。
例如在阿里云中,将当前 DNS 服务器从:
|
改成:
|

修改后需要等待 Cloudflare 检测生效。通常几分钟到几小时,最长可能需要 24 到 48 小时。
当 Cloudflare 显示:
|
说明域名已经成功接入 Cloudflare。

11. 在 Pages 中绑定自定义域名
域名接入 Cloudflare 后,进入 Pages 项目:
|
添加:
|
再添加:
|
当状态变成:
|
说明自定义域名绑定成功。

此时可以访问:
|
12. 修改 Hexo 配置
最后需要修改 Hexo 的 _config.yml,让博客生成的链接使用正式域名:
|
然后提交推送:
|
Cloudflare Pages 会自动重新部署。
13. 关于 hexo d
Cloudflare Pages 部署不依赖 Hexo 的 deploy 配置。
也就是说,Cloudflare Pages 使用的是:
|
而 hexo d 使用的是 _config.yml 里的:
|
所以两者是两条独立路线。
如果继续执行:
|
它会按照 deploy 中配置的仓库或服务器进行部署,不会影响 Cloudflare Pages 的自动部署。
14. 总结
对个人博客来说,这种方案最大的好处是成本低、维护少。GitHub 负责保存源码,Cloudflare Pages 免费负责构建和托管,域名继续正常续费即可。相比继续维护一台服务器,不需要再关心 Nginx、SSL 证书续期、服务器安全和系统更新这些问题,更适合 Hexo 这类静态博客。
这次部署中主要完成了这些事情:
- 将 Hexo 源码提交到 GitHub。
- 将主题从 Git submodule 改成普通文件夹。
- 修复 Cloudflare 构建环境无法拉取 GitHub SSH 依赖的问题。
- 创建 Cloudflare Pages 项目,并配置 Hexo 构建命令。
- 将域名
zwq-tech.xyz接入 Cloudflare。 - 配置 DNS,将主域名和
www指向 Pages 项目。 - 在 Pages 中绑定自定义域名并启用 HTTPS。
- 修改 Hexo 的站点 URL 为正式域名。
最终形成的工作流是:
|
这样以后维护博客就非常简单了,只需要专注写文章,部署交给 Cloudflare Pages 自动完成。