把 Waline 评论系统从本地 Docker 免费迁移到 Vercel + TiDB

1816 字
9 分钟
把 Waline 评论系统从本地 Docker 免费迁移到 Vercel + TiDB
2026-10-16
浏览量 加载中...

之前我的博客评论系统 Waline 一直跑在家里 Ubuntu 的 Docker 里,用的是 SQLite。这套方案能用,但依赖家里的机器和网络一直在线。这次把它迁到了 Vercel,数据库换成 TiDB Cloud,全程免费,这里记录一下过程和踩到的坑。

先回答两个问题#

Waline 算动态网页,要收钱吗?

Waline 是动态服务(评论的读写要走后端 API),但它是 Serverless 架构,可以跑在 Vercel 上。Vercel 的 Hobby 计划永久免费,但只允许个人、非商业用途,个人博客的评论系统没问题。另外 Hobby 有用量上限,超限后是停止服务而不是扣费,普通博客基本用不到。具体额度以 Vercel 官网为准。

为什么必须换数据库?

Vercel 的文件系统是只读、无状态的,SQLite 这种本地文件数据库没法用。所以需要一个云数据库。Waline 支持 LeanCloud、MySQL、MongoDB、PostgreSQL 等,我选了 TiDB Cloud Serverless(兼容 MySQL,有免费额度,Waline 官方文档有专门教程)。

选 MySQL 系而不选 PostgreSQL 的原因是:从 SQLite 导出的 INSERT 语句基本能直接导入 MySQL,而 PostgreSQL 要额外处理列名大小写和类型差异。

几个方案的对比#

迁移前我也对比过几个方向:

方案结论
Vercel + TiDBWaline 官方默认方案,文档齐全,最稳
Cloudflare Workers + D1D1 是免费数据库,但 Waline 官方不支持,后端也要改造,不推荐
Render 免费档免费服务会休眠,唤醒要几十秒,评论区加载体验差
Cloudflare Tunnel + 现有 Docker不用迁移数据,最省事,但依赖机器常开

如果机器 24 小时开着,Cloudflare Tunnel 是最省力的选择;想摆脱本地机器,就走 Vercel + TiDB。

迁移步骤#

1. 导出 SQLite 数据#

先确认数据文件和数据量:

Terminal window
cd ~/docker/waline
ls -la data
sqlite3 data/waline.sqlite ".tables"
sqlite3 data/waline.sqlite "select count(*) from wl_Comment; select count(*) from wl_Users; select count(*) from wl_Counter;"

迁移前先备份一份:

Terminal window
cp -r data data_backup

然后把三张表导出成带列名的 INSERT 语句:

Terminal window
cd data
for t in wl_Users wl_Comment wl_Counter; do
sqlite3 waline.sqlite ".headers on" ".mode insert $t" "select * from $t;" > $t.sql
done

.headers on 会让 INSERT 带上列名,避免列顺序不一致。

导出的文件里包含管理员的密码哈希和访客 IP 等信息,这些文件不要上传到公开仓库。

2. 在 TiDB Cloud 建库建表#

  1. 注册 TiDB Cloud,创建一个 Serverless 集群,记下 Host、Port(4000)、用户名、密码。
  2. 创建数据库 waline。
  3. 使用 Waline 官方提供的 MySQL 建表脚本,创建 wl_Comment、wl_Counter、wl_Users 三张表。

3. 导入数据(这里有个坑)#

我直接在 TiDB 网页的 SQL Editor 里粘贴导出的 SQL 执行,结果报了语法错误:

Parsing sql failed ... near ""like",ua,url,createdAt,updatedAt) ...

原因是 SQLite 导出的列名用的是双引号("like"、"2fa"),而 MySQL/TiDB 里双引号会被当成字符串,列名要用反引号。like 还是 MySQL 的保留字,必须加反引号。

所以导入前需要替换:

Terminal window
sed -i 's/"like"/`like`/g' wl_Comment.sql
sed -i 's/"2fa"/`2fa`/g' wl_Users.sql

用网页编辑器的话,直接手动把这两处改成反引号也行。wl_Counter 里没有这类列名,可以原样导入。

如果用命令行客户端导入,建议先执行一句,避免评论里的反斜杠被 MySQL 当成转义符:

SET SESSION sql_mode = CONCAT(@@sql_mode, ',NO_BACKSLASH_ESCAPES');

导入后核对条数是否和 SQLite 一致:

SELECT COUNT(*) FROM wl_Users;
SELECT COUNT(*) FROM wl_Comment;
SELECT COUNT(*) FROM wl_Counter;

4. 部署 Waline 到 Vercel(第二个坑)#

我一开始直接 fork 了 Waline 的整个 GitHub 仓库,然后在 Vercel 里导入。Vercel 把它识别成了 docs(文档站)、server(Container)和 app(前端)三个子项目,没有一个是能直接部署的评论服务。

正确做法是使用 Waline 官方文档「Vercel 部署」页面里的 Deploy 按钮。它会基于一个很小的模板,在你的 GitHub 下创建新仓库,模板里引用的是已发布的服务端包,部署后就是可用的评论服务。之前 fork 的仓库可以删掉。

第一次部署因为还没配数据库,打不开或报错是正常的。

5. 配置环境变量(第三个、第四个坑)#

在 Vercel 项目的 Settings → Environment Variables 里添加变量。

数据库变量要用 Waline 官方 TiDB 教程里的 TIDB_* 这一组,而不是通用的 MYSQL_*:

变量值
TIDB_HOSTTiDB 集群的 Host
TIDB_PORT4000
TIDB_DBwaline
TIDB_USER用户名(Serverless 的用户名带有前缀,要完整复制)
TIDB_PASSWORD密码
JWT_TOKEN随机字符串,建议新生成,不要沿用旧的
SITE_NAME站点名称
SITE_URL博客地址
AUTHOR_EMAIL博主邮箱

几点说明:

  • 变量类型:密码和 JWT_TOKEN 选 Secret(保存后不可回看);Host、端口、库名等选 Config,方便以后核对。用户名带前缀容易漏,建议选 Config。
  • 环境选 Production 即可。
  • 我原来在 Docker 里设置了 TZ,在 Vercel 上加这个变量会提示 reserved(系统保留名),不能设置,直接跳过。评论时间在前端会按浏览器本地时区显示,不影响使用。
  • 改环境变量不会自动触发部署,要到 Deployments 里对最新一次部署点 Redeploy 才生效。

6. 验证#

部署完成后:

  1. 打开 https://你的vercel域名/ui,用博主账号登录,说明用户表导入成功。
  2. 在评论管理里能看到旧评论,说明评论表导入成功。
  3. 打开服务根路径时评论区是空的,这是正常的,因为 Waline 的评论按页面路径存储,示例页的路径是 /,旧评论属于你博客里的各个页面路径。

评论时间在管理页里会比数据库里的值多 9 个小时,这是因为数据库存 UTC,页面按东京时区显示,不是数据错误。

7. 收尾#

  1. 把博客前端 Waline 配置里的 serverURL 改成新的地址,本地预览确认旧评论和浏览量都在。
  2. 在 Vercel 项目的 Settings → Domains 绑定自己的子域名(DNS 加 CNAME),前端改用这个域名。*.vercel.app 在国内访问不太稳定,绑自己的域名也方便以后更换部署而不改前端。
  3. 确认一切正常后,再添加 SECURE_DOMAINS 环境变量做安全域名白名单,多个域名用英文逗号分隔,不带 https://,然后 Redeploy。先测通再加白名单,出问题时好定位。
  4. 最后 docker compose down 停掉本地容器,data 备份先保留一段时间。

关于后续更新#

Vercel 关联了 GitHub 仓库,每次 push 到生产分支都会自动拉取代码并重新部署,不需要手动操作。例外是改环境变量,必须手动 Redeploy。

总结#

整个迁移的核心其实就两件事:把 SQLite 数据搬到云端 MySQL 兼容数据库,以及用官方模板部署服务端并配好环境变量。踩的坑集中在三处:

  1. SQLite 导出的双引号列名在 MySQL 里要换成反引号;
  2. 不能直接 fork 整个 Waline 仓库部署,要用官方的一键部署模板;
  3. TiDB 要用 TIDB_* 变量,TZ 在 Vercel 上是保留名不能设置。

迁完之后评论服务不再依赖家里的机器,Vercel 和 TiDB 的免费额度对个人博客也足够了。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

评论区

Profile Image of the Author
加菲魚
堆内存中的一个持久化对象。
分类
标签
站点统计
文章
30
分类
6
标签
20
总字数
38,251
访问量
...
访客数
...
运行时长
0 天
最后活动
0 天前

目录