前言

Hexo Butterfly + Waline + Supabase 全链路故障修复与维护手册

** 文档版本:** 2026 年 2 月(完整修订版)
** 适用场景:** Hexo 博客(Butterfly 主题)更新后,评论系统迁移至 Vercel + Supabase 架构,解决留言板失效、数据库连接报错及数据迁移问题。


正文

第一阶段:前端配置 (Hexo Butterfly 主题)

** 问题背景:** 更新 Butterfly 主题或更换 Waline 后端地址后,评论区消失,或者留言板加载不出以前的评论。

1. 核心配置检查 (_config.butterfly.yml)

在主题配置文件中,必须准确填写 Waline 的新后端地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
# _config.butterfly.yml

comments:
use: Waline # 确保启用了 Waline
text: true # 是否显示评论按钮
lazyload: true # 推荐开启懒加载
count: true # 显示评论数

waline:
serverURL: [https:// 你的 Vercel 自定义域名. com](https:// 你的 Vercel 自定义域名. com) # ❌ 不要填 Vercel 原始域名,✅ 填绑定好的自定义域名
pageview: true # 文章阅读量统计
option:
# 其他可选配置...

2. 留言板 (Message Board) 路径映射问题 (关键!)

** 痛点:** 留言板是自定义页面,Waline 依靠 path(路径)来识别评论归属。如果你更新主题后,页面的访问路径变了(比如从 /messageboard/ 变成了 /guestbook/),旧评论就会“消失”。

  • ** 现象 **:文章页评论正常,但 “留言板 | Tamsiree” 显示 0 条评论。
  • ** 排查依据 **:根据你的备份文件 waline.json,留言板的历史评论全部存储在 /messageboard/ 这个路径下。
  • ** 解决方案 **:
    • ** 检查 Front-matter**:打开你博客源码中的 source/messageboard/index.md(或 guestbook/index.md)。
    • ** 强制指定 path**:为了防止主题生成的链接带 index.html 或结尾斜杠不一致,建议在 Front-matter 中显式指定 Waline 的 path。
    1
    2
    3
    4
    5
    6
    ---
    title: 留言板
    date: 2024-01-01
    comments: true
    mw_path: /messageboard/ # 部分主题支持显式指定 path,或者依靠文件夹名称
    ---
    • ** 验证方法 **:在浏览器访问你的留言板,F12 打开控制台,看 Waline 发出的请求是否包含 path=/messageboard/

第二阶段:域名与网络基础

** 问题背景:** Vercel 默认域名被阻断,或后端无法连接。

1. 域名策略

  • ** 必须绑定自定义域名 **:在 Vercel 后台 Settings -> Domains 绑定 comment.yourdomain.com
  • **DNS 解析 **:在 Cloudflare/Dnspod 添加 CNAME 记录指向 cname.vercel-dns.com
  • ** 前端调用 **:Hexo 主题配置里的 serverURL 必须用这个自定义域名。

第三阶段:后端连接 (Vercel <-> Supabase)

** 问题背景:** 报错 500: Not initializedNot IPv4 compatible。Vercel 无法连接 Supabase 的 IPv6 直连地址。

✅ 解决方案:环境变量拆分

在 Vercel 后台 (Settings -> Environment Variables),** 禁用 ** 单一的 DATABASE_URL,改为 ** 拆分填写 **:

变量名 填写值示例 关键说明
PG_HOST aws-0...pooler.supabase.com ** 核心!** 必须用 pooler 地址(aws 开头),不能用 db. 开头。
PG_PORT 5432 必须用 Session 模式端口 5432
PG_USER postgres. 你的项目 ID ** 易错!** 必须包含中间的点(Supabase Pooler 用户名格式)。
PG_PASSWORD ****** 数据库密码。
PG_DB postgres 默认数据库名。
PG_SSL true ** 必填!** 显式开启 SSL 加密。

第四阶段:数据库结构 (SQL 修复)

** 问题背景:** 报错 relation "wl_Counter" does not exist 或缺少 github 等字段。

✅ 解决方案:SQL 补全

登录 Supabase -> SQL Editor 执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 1. 创建计数表
CREATE TABLE IF NOT EXISTS wl_Counter (
id SERIAL PRIMARY KEY,
url VARCHAR(255) NOT NULL UNIQUE,
time INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 2. 补全社交字段(防止导入报错)
ALTER TABLE wl_Users ADD COLUMN IF NOT EXISTS "2fa" VARCHAR(255);
ALTER TABLE wl_Users ADD COLUMN IF NOT EXISTS "github" VARCHAR(255);
ALTER TABLE wl_Users ADD COLUMN IF NOT EXISTS "twitter" VARCHAR(255);
ALTER TABLE wl_Users ADD COLUMN IF NOT EXISTS "facebook" VARCHAR(255);
ALTER TABLE wl_Users ADD COLUMN IF NOT EXISTS "google" VARCHAR(255);
ALTER TABLE wl_Users ADD COLUMN IF NOT EXISTS "weibo" VARCHAR(255);
ALTER TABLE wl_Users ADD COLUMN IF NOT EXISTS "qq" VARCHAR(255);

第五阶段:数据迁移 (导入报错修复)

** 问题背景:** 导入 waline.json 时报错 duplicate key value violates unique constraint

✅ 解决方案:清洗流程

  1. ** 清洗备份文件 **:
    • 问题源头:备份文件中 Counter 数组存在重复 URL(如两条 / 首页记录)。
    • 操作:使用脚本去重,保留 time(阅读量)最大的记录。
  2. ** 清空残留数据 **:
    • Supabase SQL: TRUNCATE TABLE wl_Counter, wl_Comment, wl_Users RESTART IDENTITY;
  3. ** 重新导入 **:上传清洗后的 json 文件。

第六阶段:长期维护 (防休眠保活)

** 问题背景:** Supabase 免费版 7 天无请求会自动暂停,导致评论区报错。

✅ 解决方案:UptimeRobot 监控

配置定时任务,伪装成 Hexo 前端去 “戳” 一下数据库。

  • ** 工具 **:UptimeRobot
  • ** 类型 **:HTTP(s)
  • ** 频率 **:5 min
  • **URL (核心配置)**:
    1
    https:// 你的 Vercel 自定义域名 / api/comment?path=/messageboard/

    ** 为什么填这个?** 必须访问 /api/comment 接口,并带上 ?path=/messageboard/(留言板路径),强制触发数据库读取操作,从而重置 7 天倒计时。


🎉 故障排查速查表

  1. ** 评论区转圈 / 500** -> 检查 Vercel 环境变量(SSL/Pooler 地址)。
  2. ** 提示表不存在 ** -> 去 Supabase 执行 SQL 建表。
  3. ** 导入报 Key 重复 ** -> 清洗 JSON 文件,清空数据库重试。
  4. ** 留言板没评论 ** -> 检查 Hexo 页面 URL 是否与数据库 path 一致。
  5. ** 过几天突然挂了 ** -> 检查 UptimeRobot 是否正常运行,去 Supabase 后台点击 “Restore”。

to be continued…