Hexo 博客部署到 Cloudflare Workers
Cloudflare Pages 影响了我博客的评论系统
为了借助 Cloudflare Pages 实现全球加速和持续集成/持续部署(CI/CD),我的 博客 (以下简称 本博)一开始有一个镜像是部署在 Cloudflare Pages [1]。
但是,我后来发现 Cloudflare Pages 会自动移除 URL 末尾的扩展名,例如访问 https://example.tld/file123.html
,它就会 302 跳转到 https://example.tld/file123
。官方称之为 Route matching(路由匹配)[2]。Route matching 无法手动关闭。
这个功能影响了 本博 评论的加载。本博 的评论系统是 Valine,它是根据静态页面的文件名来储存评论数据的,比方说,它会把 https://example.tld/file123.html
这个页面的所有评论放在数据库的 file123.html
表中。所以 本博 不同镜像的同一篇文章会共享同样的评论。但是 Route matching 去掉了 .html
后缀,导致 Valine 评论系统会在数据库新建一个 file123
表,从而使得部署在 Cloudflare Pages 上的 本博镜像 不能与其他的镜像共享评论。
但是我又不想放弃 Cloudflare,毕竟它的节点遍布全球(中国大陆除外),真的能够加速全球访问啊。
两种可行的解决方案
我想出两种解决方案:
-
放弃 Cloudflare Pages,而是部署到 Cloudflare Workers,后者也是利用 Cloudflare 的 CDN 加速全球访问。
-
二是修改 本博 的
_config.yml
,去掉每个静态页面的 URL 的.html
扩展名,然后配置 301 跳转。
尽管两个方案都挺麻烦,但是我倾向于用第一个,因为改 URL 和配置跳转都会影响搜索引擎对 本博 的收录。
部署到 Cloudflare Workers
前人[3][4][5]已经写得非常明确了,此处结合 本博 的实际作了补充,并且详细解读配置文件的编写。
创建 Cloudflare API 令牌
打开 Cloudflare 的 API 令牌申请页面 ,在此申请一个 API 令牌(API token)。
点击“创建令牌”。
找到“编辑 Cloudflare Workers”,点击右侧的“使用模板”。
去掉“账户设置”和“用户详细信息”权限。
“账户资源”和“区域资源”按照权限最小化的原则设置。然后点击“继续以显示摘要”。
最后,点击“创建令牌”,完成。
将生成的令牌(一个字符串)保存在安全的地方,这个令牌只显示一次,下次不再显示。
安装 Wrangler
以下以 PowerShell 为例说明命令。假设我的博客源码在 C:\Users\Kukmoon\Kukmoon_blog
文件夹。
1 |
|
初始化项目
1 |
|
Cloudflare Workers 会为项目分配一个四级域名。上述命令中的 blog
是项目的名称,也是域名的一部分,读者可以换成自己喜欢的名称。我在 Cloudflare 的用户名是 kukmoon
,那么 本博 部署到 Cloudflare Workers 以后,URL 就是 https://blog.kukmoon.workers.dev。
执行以上命令,会在我的博客源码文件夹中生成配置文件 wrangler.toml
和几个文件夹。下一步需要修改配置文件。
配置 wrangler.toml
用文本编辑器打开 wrangler.toml
1 |
|
详细解读:
-
name:上一步的命令
wrangler init --site blog
中的blog
。 -
account_id:我的 Cloudflare 账户 ID。在 Cloudflare 的面板 中,点开绑定到 Cloudflare 的某个域名,在右下角“API”域名中查找“账户 ID”。
-
route:自定义域名。注意:一定不能忽略末尾的
/*
,这是由 Cloudflare 的匹配规则决定的。 -
zone_id:网站的区域 ID。在 Cloudflare 的面板 中,点开绑定到 Cloudflare 的某个域名,在右下角“API”域名中查找“区域 ID”。
-
workers_dev:是否启用 Cloudflare Workers 为项目分配的四级域名,此处为
https://blog.kukmoon.workers.dev
设置为true
即可。 -
site:要把
bucket
设为./public
,即 Hexo 渲染生成的静态页面所在的文件夹。
配置 API 令牌
保存以上文件后,运行 wrangler config
按照提示输入刚刚获取到的 API 令牌。
预览和发布
在博客源码所在的文件夹下执行以下命令。
生成静态文件。
1 |
|
预览。运行下述命令可以预览,这会将 bucket
中的文件上传到 Cloudflare Workers KV (Cloudflare Workers 的对象存储空间)中,而且浏览器会自动打开一个窗口进行预览(如果没有……手动打开提供的链接吧)。如果没有开梯子,墙内访问速度会比较慢。
1 |
|
预览结束后,可以按 Ctrl+C
中断预览。
若预览正常工作,运行下述命令即可将它发布到 Cloudflare Workers:
1 |
|
配置域名解析(路由)
我指定了自定义域名是 blog2.kukmoon.com
,但是这个域名必须指定 DNS 解析才能访问。
在 Cloudflare 中添加一条 CNAME 记录,让 blog2.kukmoon.com
指向 blog.kukmoon.worker.dev
。
注意:由于 Cloudflare Workers 要求自定义域名必须提供对应的区域 ID,因此自定义域名所使用的二级域名必须绑定到 Cloudflare。
使用 GitHub Actions 持续部署
记得为博客源码所在的 GitHub 仓库 kukmoon_blog
添加一个 secret,名称为 CF_WORKERS_TOKEN
,把 Cloudflare 的 API 令牌复制粘贴过去。
这篇文章[3]提供的 workflow 脚本因为缩进不准确和 persist-credentials: false
参数错误而无法运行,我修正了这两个,新的 workflow 如下:
1 |
|
适用于 本博 的综合性的 workflow 参见此处[6]。
番外:能不能把文件名命名为 file123.html.html
不能。Cloudflare 社区 有人反映类似的情况会直接 404 (不好意思,源贴找不到了)。这说明 Cloudflare Pages 对双扩展名的文件进行 URL 跳转处理时存在 bug。由于正则表达式符合贪心算法,我估计 Cloudflare Pages 的开发者用正则表达式匹配 URL,结果把 URL 中左起第一个句点后面的字符都删除了。
图片版权
头图:Banner Image by milkusmaximus from Pixabay