我本来的博客是部署在github pages上,后来迁移到了netlify上,但是总是效果不佳(访问速度慢、国内访问失败)。于是在2026年初,重新托管到了cloudflare pages上面,CF的好处是速度明显变快(得益于其CDN),局限性是国内IP访问依然失败,于是购入一个域名liu-cy.top,依旧选择了cloudflare托管,同时更换了图床为Cloud Flare R2+piclist,不得不说,Cloud Flare真是财大气粗的金主。现在将这些过程和内容依次记录下来。以待后续维护和查阅

特别鸣谢:

  • Gemini
  • Cloudflare
  • Github
  • spaceship

Hexo 博客部署:GitHub + Cloudflare Pages

更新时间:2026-01-23
架构逻辑:本地写文章 -> 推送源码到 GitHub -> Cloudflare Pages 自动抓取源码并构建 (hexo g) -> 发布静态网页
核心优势:速度极快、自动 HTTPS、无需手动上传 public 文件夹。

第一部分:本地环境准备 (源码清洗)

在将博客推送到 GitHub 之前,必须确保本地文件夹 SinohopesBlog 干净且安全。

1. 检查必要文件

确保根目录下包含以下核心文件(必须提交):

  • _config.yml (站点配置文件)
  • package.json & package-lock.json (依赖包列表,Cloudflare 靠它自动安装环境)
  • source/ (存放文章 Markdown 和图片)
  • scaffolds/ (文章模板)
  • themes/node_modules/ (取决于你的 Butterfly 主题安装方式,NPM 安装的在 node_modules 里,但这部分通常忽略,靠服务器下载)

2. 配置 .gitignore (极度重要)

在根目录下新建或编辑 .gitignore 文件,必须包含以下内容(防止垃圾文件和敏感信息上传):

1
2
3
4
5
6
7
8
9
10
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy_git/
.git/
# 你的敏感文件 (图床Token等)
(极度重要!)图床的Token. t

3. 初始化 Git 仓库

SinohopesBlog 文件夹内,右键打开终端:

1
2
3
4
5
6
7
8
9
10
11
# 1. 初始化(如果是从旧文件夹复制过来的,这步会重置 Git 状态)
git init

# 2. 这里的 main 是现在 GitHub 推荐的主分支名
git branch -M main

# 3. 添加所有文件(.gitignore 里忽略的不会被添加)
git add .

# 4. 首次提交
git commit -m "First commit for Cloudflare Pages"

第二部分:GitHub 仓库设置

1. 创建新仓库

  • 登录 GitHub -> 点击右上角 + -> New repository
  • Repository name: blog-source (建议以此命名,区分于旧的 blog_img)。
  • Visibility: 建议选 Private (私有),因为这里面可能有你的草稿或配置文件,私有更安全。Cloudflare Pages 支持读取私有库。
  • 点击 Create repository

2. 关联并推送

回到本地终端,执行 GitHub 页面上提示的代码:

1
2
3
4
5
# 关联远程仓库 (换成你自己的地址)
git remote add origin https://github.com/你的用户名/blog-source.git

# 推送到 GitHub
git push -u origin main

(此时刷新 GitHub 页面,应该能看到你的源码,且没有 node_modules 这种大文件夹)


第三部分:Cloudflare Pages 设置

1. 连接 Git

  • 登录 Cloudflare Dashboard -> 左侧菜单 Workers & Pages -> Overview
  • 点击 Create application -> 切换到 Pages 标签 -> 点击 Connect to Git
  • 登录 GitHub:授权 Cloudflare 访问你的仓库(如果选了仅授权特定仓库,记得把 blog-source 选上)。
  • 选择仓库:选中 blog-source -> Begin setup

2. 构建配置 (Build Settings)

这是最关键的一步,告诉 Cloudflare 怎么把你的 Markdown 变成网页:

  • Project name: sinohopes-blog (随意,会变成默认域名的前缀)
  • Production branch: main
  • Framework preset (框架预设): 选择 Hexo (选了之后下面的会自动填好)。
  • Build command (构建命令): hexo generate (或者 npm run build)
  • Build output directory (输出目录): public

3. 环境变量 (可选但推荐)

如果你的本地 Node.js 版本较新(比如 v18/v20),建议显式告诉 Cloudflare 使用该版本,避免版本不兼容报错。

  • 点击 Environment variables (advanced)
  • 添加变量:
    • Variable name: NODE_VERSION
    • Value: 20 (或者你本地 node -v 看到的版本号)

4. 开始部署

  • 点击 Save and Deploy
  • Cloudflare 会开始跑进度条:Cloning -> Building -> Deploying
  • 如果看到 Success,点击访问链接,你的博客就上线了!

第四部分:绑定自定义域名 (收尾)

为了让博客地址好看(比如 www.sinohopes.top):

  1. 在 Pages 项目页面 -> Custom domains (自定义域)。
  2. 点击 Set up a custom domain
  3. 输入:www.sinohopes.top (或者 blog.sinohopes.top)。
  4. Cloudflare 会自动更新 DNS 记录。
  5. 等待几分钟,SSL 证书生效后即可访问。

第五部分:日常维护工作流

以后写博客,你只需要做这件事,不需要再敲 hexo ghexo d

  1. 本地写作:在 VSCode 里写文章,用 PicList 粘贴图片。
  2. 本地预览hexo s (检查文章样式)。
  3. 提交推送
    1
    2
    3
    git add .
    git commit -m "更新文章: xxxx"
    git push
  4. 自动发布:Cloudflare 监测到你 Push 了代码,会自动拉取并重新构建发布(通常 1-2 分钟内生效)。

常见故障排查

  • 构建失败 (Build Failed)
    • 查看 Cloudflare 的构建日志。
    • 如果是 Cannot find module...:检查 package.json 是否上传了。
    • 如果是 Node version...:按第三部分去设置环境变量 NODE_VERSION
  • 样式丢失/排版乱
    • 检查 _config.yml 里的 url 设置,最好填你最终的自定义域名。
    • 检查 Butterfly 主题的配置文件是否正确上传。

Cloudflare R2 + PicList 图床配置

第一部分:Cloudflare R2 端设置

1. 创建存储桶 (Bucket)

  • 路径:Cloudflare Dashboard -> R2 -> Create bucket
  • 名称blogimages (或者你设定的其他名称,只能小写)
  • 位置:Automatic (自动)

2. 开启公开访问 (Public Access)

  • 路径:进入 blogimages 桶 -> Settings (设置) -> Public Access
  • 方式 A (自定义域 - 推荐)
    • 点击 “Connect Domain”。
    • 输入:img.sinohopes.top (示例)。
    • 等待 DNS 生效。
  • 方式 B (R2.dev - 免费)
    • 找到 “Public R2.dev Bucket URL”。
    • 点击 “Enable” (启用)。
    • 记录链接https://pub-xxxxxx.r2.dev (注意:这是访问域名,不是上传接口)。

3. 获取 S3 API 接口 (Endpoint)

  • 路径:进入 blogimages 桶 -> Settings -> Bucket Details
  • 操作:复制 S3 API 下方的链接。
  • ⚠️ 关键处理必须删除链接末尾的存储桶名称!
    • 原始:https://<AccountID>.r2.cloudflarestorage.com/blogimages
    • 修正后 (填入 PicList 用)https://<AccountID>.r2.cloudflarestorage.com

4. 生成上传凭证 (API Tokens)

  • 路径:R2 首页 -> 右下角”Account Details”-> “Manage R2 API Tokens” -> “Create API token”
  • 配置
    • Token name: PicList-Write
    • Permissions (权限):必须选择 Admin Read & Write (管理员读写)
    • TTL: Forever (永久)
  • ⚠️ 备份数据 (只显示一次,必须保存):
    • Access Key ID
    • Secret Access Key

第二部分:PicList 客户端配置

  • 图床类型:选择 Amazon S3 (内置)
  • 配置参数表
参数项 填写内容 / 注意事项
图床配置名 CF-R2 (自定义)
AccessKeyId 填入上面获取的 Access Key ID
SecretAccessKey 填入上面获取的 Secret Access Key
Bucket blogimages (你的桶名)
文件路径 {year}/{month}/{fileName} (推荐)
Region auto (⚠️ 必须手动输入 auto,不可选其他)
自定义节点 https://<AccountID>.r2.cloudflarestorage.com
(⚠️ 严禁/blogimages 后缀)
代理 (留空)
自定义域名 https://pub-xxxxxx.r2.dev
(或者你的自定义域名,⚠️ 严禁带末尾斜杠 /)
网址后缀 (留空)
s3ForcePathStyle No (关闭)
拒绝无效TLS证书 No (关闭)
访问策略 (ACL) private (⚠️ 核心易错点:千万别选 public-read)

第三部分:常见报错与维护

1. 报错 “The specified bucket does not exist”

  • 原因:自定义节点 (Endpoint) 填错了。
  • 解决:检查“自定义节点”一栏,是不是如果不小心把 bucket 名字粘进去了?删掉末尾的 /blogimages

2. 报错 “NotImplemented: Header ‘x-amz-acl’…”

  • 原因:访问策略 (ACL) 选了 R2 不支持的选项(如 public-read-write)。
  • 解决
    • 方法一:在 PicList 设置里把“访问策略”改为 private
    • 方法二:编辑 PicList 配置文件,搜索 "acl": "...",直接删除这一整行

3. 上传成功但图片无法访问 (404/403)

  • 原因:自定义域名填错,或者 R2 后台没开启 Public Access。
  • 解决:检查 PicList 里的“自定义域名”是否能直接在浏览器打开?检查 R2 后台的“允许访问”是否被误关了。

Hexo + Cloudflare Pages 自定义域名绑定指南

适用架构:

  • 源码/生成: Hexo + Butterfly 主题
  • 代码托管: GitHub
  • 部署/托管: Cloudflare Pages
  • 域名注册商: Spaceship
  • DNS 解析: Cloudflare (托管模式)

第一阶段:域名接入 Cloudflare (DNS 托管)

这一步的核心是将域名的解析权从 Spaceship 转移给 Cloudflare,利用 Cloudflare 强大的 CDN 和 SSL 功能。

  1. 在 Cloudflare 添加站点

    • 登录 Cloudflare Dashboard。
    • 点击 “Websites” -> “Add a site”
    • 输入你的根域名(例如:liu-cy.top)。
    • 选择 Free Plan (免费计划) 并继续。
    • DNS 扫描页直接点击 Continue
  2. 获取 Nameservers (NS 记录)

    • Cloudflare 会给出两个 NS 地址(例如 xxxx.ns.cloudflare.com)。
    • 复制这两个地址
  3. 在 Spaceship 修改 Nameservers

    • 登录 Spaceship -> Launchpad -> Domain List
    • 找到域名,点击 Manage (或箭头展开)。
    • 找到 Nameservers 栏目,点击右上角的 Change 按钮。
    • 选择 Custom DNS
    • 分别填入刚才复制的两个 Cloudflare NS 地址。
    • 点击保存 (Save)。
  4. 确认生效

    • 回到 Cloudflare 点击 “Done, check nameservers”
    • 等待收到标题为 “Active” 的邮件,表示域名已成功接入。

第二阶段:Cloudflare Pages 绑定域名

这一步是将你的 Cloudflare Pages 项目与新域名关联。

  1. 进入 Pages 项目

    • Cloudflare 后台 -> Workers & Pages -> 点击你的 Hexo 项目。
    • 点击顶部标签栏的 Custom domains
  2. 绑定根域名

    • 点击 Set up a custom domain
    • 输入 liu-cy.top
    • Cloudflare 会自动配置 DNS 记录,点击 Activate domain
  3. 绑定 WWW 域名 (强烈建议)

    • 再次点击 Set up a custom domain
    • 输入 www.liu-cy.top
    • 点击 Activate domain
    • 作用:保证用户输入带 www 的网址也能访问,Cloudflare 会自动处理跳转。

第三阶段:本地 Hexo 配置更新 (SEO 与 链接适配)

虽然域名能访问了,但 Hexo 内部生成的 Sitemap、RSS 和部分固定链接仍需指向新域名。

  1. 修改站点配置文件
    打开本地博客根目录下的 _config.yml

    1
    2
    3
    4
    5
    6
    7
    # _config.yml

    # 修改 URL 为新域名 (注意是 https)
    url: https://liu-cy.top

    # 确保 root 仍然是 /
    root: /
  2. 检查主题配置文件 (Butterfly)
    检查 _config.butterfly.yml,查看是否有写死的旧链接(通常社交图标、页脚链接等)。如果没有硬编码旧域名,则无需修改。

  3. 提交部署

    1
    2
    3
    git add .
    git commit -m "chore: update domain url to liu-cy.top"
    git push

    等待 Cloudflare Pages 自动构建完成。


第四阶段:测试与验证清单

部署完成后,请按以下清单进行检查:

  1. HTTPS 检查

    • 访问 https://liu-cy.top -> 是否显示安全锁标志?
    • 注:刚绑定时可能需要 15 分钟申请证书,期间可能提示不安全,属正常现象。
  2. WWW 跳转检查

    • 访问 www.liu-cy.top -> 是否能正常打开(或自动跳转到不带 www 的版本)?
  3. 旧域名检查

    • 访问原有的 xxx.pages.dev -> 应该依然可以访问(作为备用入口)。
  4. 文章内链检查

    • 点击博客内的文章,检查浏览器地址栏是否保持在 liu-cy.top 下,而不是跳回旧域名。

维护与故障排查 (FAQ)

Q1: 访问提示 “Too many redirects” (重定向次数过多)

  • 原因:Cloudflare 的 SSL 设置与 Pages 的强制 HTTPS 冲突。
  • 解决
    1. 进入 Cloudflare 后台 -> 选中你的域名。
    2. 左侧菜单 SSL/TLS -> Overview
    3. 将加密模式改为 FullFull (Strict)
    4. 切勿设置为 Flexible。

Q2: Spaceship 续费要注意什么?

  • Spaceship 只负责域名的“所有权”。每年你需要去 Spaceship 续费域名。
  • DNS 解析和 SSL 证书由 Cloudflare 免费提供,无需操作。

Q3: 我想换回 Spaceship 的 DNS 怎么办?

  • 去 Spaceship 将 Nameservers 改回 Spaceship Basic DNS
  • 去 Cloudflare 删除站点。
  • 注意:这样做会导致你的 Pages 自定义域名失效,需要重新配置 CNAME 记录。