把 Hexo 博客从 Ubuntu 迁移到 Cloudflare Pages

小镇炼丹师 Lv2

将原本由 Ubuntu、Nginx 和 Cloudflare Tunnel 提供服务的 Hexo 静态博客及站内图片完整迁移到 GitHub 与 Cloudflare Pages,让网站在 Ubuntu 关机时仍可正常访问。

前言

之前我的 Hexo 博客运行在一台没有公网 IP 的 Ubuntu 服务器上,整体链路是:

1
2
3
4
5
6
7
8
9
访客

Cloudflare

Cloudflare Tunnel

Ubuntu Nginx

/mnt/data/www/blog

每次更新文章,都需要在服务器上生成静态文件,再用 rsync 复制到 Nginx 网站目录:

1
2
3
4
5
6
7
8
cd /mnt/data/hexo-blog
npx hexo clean
npx hexo generate

sudo rsync -a --delete \
--chown=www-data:www-data \
/mnt/data/hexo-blog/public/ \
/mnt/data/www/blog/

这个方案可以正常使用,但 Hexo 生成的 public 本质上只是静态 HTML、CSS 和 JavaScript,并不需要长期运行一台 Ubuntu 服务器。因此,我将博客改成了下面的结构:

1
2
3
4
5
6
7
任意安装了 Git 的电脑编写博客
↓ git push
GitHub 私有仓库
↓ 自动触发构建
Cloudflare Pages

www.lideguo.com

迁移后,博客页面、头像、背景和文章中的本地图片都由 Cloudflare Pages 提供,不再依赖 Ubuntu 的 Nginx、图床和 Tunnel。Ubuntu 可以继续作为写作电脑,但不需要为了维持网站访问而一直开机。

如果博客还引用 img.lideguo.com、Waline 后端或其他自建服务,需要先将这些资源一并迁移。只要页面中仍有指向 Ubuntu 的地址,就还没有完全摆脱服务器依赖。

一、迁移前的目录结构

我的 Hexo 项目位于:

1
/mnt/data/hexo-blog

主要目录和文件如下:

1
2
3
4
5
6
7
hexo-blog/
├── source/ # 文章、图片和页面
├── scaffolds/ # 文章模板
├── _config.yml # Hexo 配置
├── _config.redefine.yml # Redefine 主题配置
├── package.json
└── package-lock.json

先确认博客可以在本地正常生成:

1
2
3
cd /mnt/data/hexo-blog
npm run build
test -f public/index.html && echo "构建成功"

如果 package.json 中还没有 build 命令,可以执行:

1
npm pkg set scripts.build="hexo generate"

再次查看:

1
npm pkg get scripts

正常情况下会包含:

1
2
3
{
"build": "hexo generate"
}

二、准备 Git 忽略文件

Cloudflare Pages 会根据源码重新安装依赖并生成网站,因此不需要把 node_modulespublic 和 Hexo 数据库上传到 GitHub。

在项目根目录创建 .gitignore

1
2
cd /mnt/data/hexo-blog
nano .gitignore

写入:

1
2
3
4
5
6
node_modules/
public/
db.json
.deploy_git/
*.log
.env

下面这些文件需要保留并提交:

1
2
3
4
5
6
source/
scaffolds/
_config.yml
_config.redefine.yml
package.json
package-lock.json

提交之前需要检查配置文件,确保其中没有以下敏感信息:

  • Cloudflare Tunnel Token
  • GitHub Token
  • SSH 私钥
  • 数据库密码
  • 其他 API 密钥

三、创建 GitHub 私有仓库

我在 GitHub 创建了一个名为 lideguo-blog 的私有仓库。私有仓库不会公开博客源码,但授权后 Cloudflare Pages 仍然可以读取和构建。

创建私有仓库
创建私有仓库

回到 Ubuntu,初始化 Git:

1
2
3
4
cd /mnt/data/hexo-blog
git init
git add .
git commit -m "Initial Hexo blog"

第一次提交时,我遇到了下面的错误:

1
2
Author identity unknown
Please tell me who you are.

这是因为服务器还没有设置 Git 提交者信息。配置用户名和邮箱:

1
2
git config --global user.name "MakerG9527"
git config --global user.email "你的 GitHub 邮箱"

重新提交并将分支改成 main

1
2
git commit -m "Initial Hexo blog"
git branch -M main

添加远程仓库:

1
git remote add origin git@github.com:MakerG9527/lideguo-blog.git

四、配置 GitHub SSH 密钥

第一次推送时出现:

1
2
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

原因是 Ubuntu 服务器还没有被 GitHub 授权。先检查是否已有 SSH 密钥:

1
ls -l ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub

如果不存在,就生成一对新密钥:

1
ssh-keygen -t ed25519 -C "你的 GitHub 邮箱"

按照提示一路按回车即可。随后显示公钥:

1
cat ~/.ssh/id_ed25519.pub

复制输出的完整一行,进入 GitHub:

1
2
3
Settings
→ SSH and GPG keys
→ New SSH key

填写:

1
2
3
Title:Ubuntu Hexo Server
Key type:Authentication Key
Key:粘贴 id_ed25519.pub 的内容

这里只能上传带 .pub 后缀的公钥,不能上传或泄露私钥 id_ed25519

添加完成后测试:

1
ssh -T git@github.com

成功时会显示:

1
2
Hi MakerG9527! You've successfully authenticated,
but GitHub does not provide shell access.

最后一句不是错误,只表示 GitHub 不提供普通 SSH Shell。

现在可以推送博客:

1
git push -u origin main

五、创建 Cloudflare Pages 项目

进入 Cloudflare 控制台。新版中文界面中,Pages 位于:

1
2
3
4
构建
→ 计算
→ Workers 和 Pages
→ 创建应用程序

创建应用程序
创建应用程序

创建 Pages
创建 Pages

选择:

1
2
Pages
→ 导入现有 Git 存储库

授权 GitHub 后选择:

1
MakerG9527/lideguo-blog

构建设置如下:

1
2
3
4
5
6
项目名称:lideguo-blog
生产分支:main
框架预设:Hexo(没有就选 None)
构建命令:npm run build
构建输出目录:public
根目录:留空

环境变量添加:

1
2
变量名称:NODE_VERSION
值:22

NODE_VERSION=22 表示 Cloudflare 构建网站时使用 Node.js 22,尽量与服务器上的开发环境保持一致。

Pages 的构建和部署
Pages 的构建和部署

保存并部署后,Cloudflare 会执行类似下面的流程:

1
2
3
4
获取 GitHub 源码
→ 安装 package.json 中的依赖
→ 执行 npm run build
→ 发布 public 目录

部署成功后会得到一个临时地址,例如:

1
https://lideguo-blog.pages.dev

先通过这个地址检查首页、文章、图片、分类、标签、友链、动态和手机端显示是否正常。在确认 Pages 正常以前,不要删除原有的 Tunnel 路由。

Cloudflare 官方文档:

六、将正式域名切换到 Pages

原来的 www.lideguo.com 指向 Cloudflare Tunnel:

1
2
3
4
www.lideguo.com
→ Cloudflare Tunnel
→ http://127.0.0.1:80
→ Ubuntu Nginx

确认 pages.dev 临时地址正常后,进入:

1
2
3
4
5
域名
→ 概览
→ 点击域名
→ 左侧DNS菜单
→ 记录

删除下面这条博客路由:

1
www.lideguo.com → http://127.0.0.1:80

然后添加新的记录,将www前缀绑定到pages.dev

添加CNAME记录
添加CNAME记录

等本文后面的图片迁移完成,并确认博客已经没有任何资源依赖 Ubuntu 后,再决定是否停用 img.lideguo.com 和 Cloudflared Tunnel。若还承载其他应用,则仍需保留。

接下来打开 Pages 项目:

1
2
3
4
Workers 和 Pages
→ lideguo-blog
→ 自定义域
→ 设置自定义域

输入:

1
www.lideguo.com

Cloudflare 会自动创建新的 DNS 记录并配置 HTTPS。等待状态变成“有效”或“Active”后,访问:

1
https://www.lideguo.com

设置自定义域成功
设置自定义域成功

如果电脑仍然显示旧内容,可以按 Ctrl + F5 强制刷新,或者使用无痕窗口测试。

自定义域的官方说明:

七、把头像、背景和文章图片迁移到 Pages

域名切换完成并不代表已经完全摆脱 Ubuntu。如果主题配置或 Markdown 仍然引用 Ubuntu主机上的图床,Ubuntu 关机后对应图片依然会失效。

先搜索整个项目:

1
2
3
4
5
6
7
cd /mnt/data/hexo-blog

grep -Rni \
--exclude-dir=.git \
--exclude-dir=node_modules \
--exclude-dir=public \
"img.lideguo.com" .

我的头像和背景原来配置为:

1
2
3
4
avatar: "https://img.lideguo.com/site/avatar-v1.jpg"

light: "https://img.lideguo.com/site/blue-background.jpg"
dark: "https://img.lideguo.com/site/blue-background.jpg"

在图床仍可访问时,把它们保存到 Hexo 的 source 目录:

1
2
3
4
5
6
7
8
9
10
cd /mnt/data/hexo-blog
mkdir -p source/images/site

curl -fL \
"https://img.lideguo.com/site/avatar-v1.jpg" \
-o source/images/site/avatar-v1.jpg

curl -fL \
"https://img.lideguo.com/site/blue-background.jpg" \
-o source/images/site/blue-background.jpg

然后将 _config.redefine.yml 改为站内路径:

1
2
3
4
avatar: "/images/site/avatar-v1.jpg"

light: "/images/site/blue-background.jpg"
dark: "/images/site/blue-background.jpg"

source/images/site 中的文件会在构建时输出到 public/images/site,最终由 www.lideguo.com 直接提供。

对于文章图片,可以采用文章资源文件夹:

1
2
3
4
5
6
7
source/_posts/博客搭建/静态博客托管到cloudflare.md
source/_posts/博客搭建/静态博客托管到cloudflare/
├── 创建private项目.png
├── cloudflare创建应用程序.png
├── cloudflare创建pages.png
├── pages的构建和部署.png
└── 设置自定义域成功.png

Markdown 中直接写图片文件名:

1
![Pages 的构建和部署](pages的构建和部署.png)

并确认 _config.yml 中启用了文章资源文件夹:

1
post_asset_folder: true

如果使用普通 Markdown 图片语法,还可以配置:

1
2
3
marked:
prependRoot: true
postAsset: true

迁移完所有图片后执行本地构建检查:

1
2
3
4
5
npx hexo clean
npx hexo generate

test -f public/images/site/avatar-v1.jpg && echo "头像正常"
test -f public/images/site/blue-background.jpg && echo "背景正常"

再次搜索项目中的旧图床地址。教程代码块中的文字可以保留,但主题配置和真正的 Markdown 图片引用中不应再依赖它:

1
2
3
4
5
grep -Rni \
--exclude-dir=.git \
--exclude-dir=node_modules \
--exclude-dir=public \
"img.lideguo.com" .

至此,即使 Ubuntu 和 Cloudflared 都停止运行,博客页面、头像、背景和随文章提交的图片仍能正常访问。

八、以后如何发布文章

迁移前的发布方式是:

1
2
3
4
hexo clean
→ hexo generate
→ rsync
→ Nginx

迁移后的发布方式变成:

1
2
3
4
5
cd /mnt/data/hexo-blog

git add -A
git commit -m "发布新文章"
git push

推送后,GitHub 和 Cloudflare Pages 会自动完成剩余工作。可以进入 Cloudflare Pages 项目的“部署”页面查看构建状态和日志。

Ubuntu 不是唯一的写作设备。以后也可以在其他电脑克隆私有仓库,修改后再提交。Ubuntu 关机只会暂时影响在这台机器上编辑文章,不会影响已经部署的网站。

本地预览仍然使用:

1
npx hexo server -i 0.0.0.0

九、迁移后的优点

迁移到 Cloudflare Pages 后,有几个很直观的变化:

  1. 博客不再依赖 Ubuntu 是否开机。
  2. 不需要维护博客专用的 Nginx 配置。
  3. 不需要手动复制 public 目录。
  4. GitHub 同时保存了博客源码和历史版本。
  5. 每次推送都会自动构建和部署。
  6. HTTPS 和 CDN 由 Cloudflare 负责。
  7. Ubuntu 关机或出现故障时,博客及站内图片仍然可以访问。
  8. 头像、背景和文章图片跟随 Git 版本一起管理。

不过,Pages 主要适合静态网站。如果使用 Waline、数据库、在线上传接口或其他动态服务,相关功能仍需单独的云服务。本文使用的 Giscus 评论由 GitHub 提供,因此不依赖 Ubuntu。

总结

这次迁移并不是否定 Ubuntu、Nginx 和 Cloudflare Tunnel 的方案。Tunnel 很适合将没有公网 IP 的内网服务发布到互联网,但对于已经构建完成的 Hexo 静态网站,直接交给 Cloudflare Pages 托管更加简单。

完全迁移后的结构如下:

1
2
3
4
5
6
7
博客源码:任意电脑 + Git
源码备份:GitHub 私有仓库
自动构建:Cloudflare Pages
正式域名:www.lideguo.com
头像与背景:source/images/site + Cloudflare Pages
文章图片:source/_posts 资源文件夹 + Cloudflare Pages
评论系统:Giscus

以后写完文章只需要一次 git push,网站就会自动更新。只要所有实际资源都已经提交到 GitHub,Ubuntu 就可以关机,网站仍由 Cloudflare Pages 正常提供服务。对个人静态博客来说,这套方案兼顾了部署便利、访问速度和后续维护成本。

  • 标题: 把 Hexo 博客从 Ubuntu 迁移到 Cloudflare Pages
  • 作者: 小镇炼丹师
  • 创建于 : 2026-08-06 11:12:54
  • 更新于 : 2026-08-06 11:12:54
  • 链接: https://www.lideguo.com/2026/08/06/博客搭建/静态博客托管到cloudflare/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论