知识门户

Back

手把手教你搭建 Waline 评论系统:从零到上线,踩坑全记录#

这篇文章会带你一步一步搭建 Waline 评论系统。不需要懂后端开发,不需要会写 SQL,跟着操作就行。

零、先搞清楚我们要搭什么#

一个带评论功能的博客,实际上由三样东西组成:

你写的评论 ──→ 存到哪里? ──→ 怎么显示出来?
plaintext

传统网站(比如 WordPress)这三件事都在同一台服务器上。静态博客(比如我们的 Astro 站点)没有后端,所以需要额外拼装两个服务:

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   你的博客       │     │   Waline 后端    │     │   数据库         │
│  (Netlify)      │ ──→ │   (Vercel)      │ ──→ │   (Supabase)    │
│                 │ ←── │                 │ ←── │                 │
│  显示评论       │     │  处理评论数据    │     │  存储评论数据    │
│  显示浏览量     │     │  提供 API 接口   │     │  存储浏览量      │
│                 │     │                 │     │  存储点赞        │
└─────────────────┘     └─────────────────┘     └─────────────────┘
    前端(已有)           后端(需要新建)         数据库(需要新建)
plaintext

三者的关系可以用一个生活类比来理解:

  • 数据库(Supabase) = 仓库。评论、浏览量、点赞都存在这里。
  • Waline 后端(Vercel) = 仓库管理员。你不直接进仓库拿东西,你跟管理员说”我要这篇文章的评论”或”我要存一条新评论”,管理员帮你去仓库操作。
  • 前端(你的博客) = 店门口。顾客在店门口看到评论、写评论,背后是管理员在仓库里忙活。

一、准备工作#

1.1 确认前端组件已就位#

astro-pure 主题已经把 Waline 的”店门口”部分做好了,项目里已经有这些文件,不需要额外写代码:

文件作用
src/components/waline/Comment.astro评论区组件(含点赞按钮)
src/components/waline/PageInfo.astro显示”X 次浏览 · Y 条评论”
src/components/waline/Pageview.astro浏览量计数器
public/icons/heart-item.svg点赞用的心形图标

这些组件现在处于”休眠”状态——因为 Waline 后端的地址还没填,它们不知道该找谁要数据。等我们部署好 Waline 后端,填上地址,它们就活了。

1.2 列一下你需要准备的东西#

  • 一个 GitHub 账号(用来登录 Vercel 和 Supabase)
  • 一个浏览器
  • 大约 30 分钟时间
  • 不需要懂代码

二、第一步:注册并创建 Supabase 数据库#

Supabase 是一个云数据库服务,简单理解就是”放在云上的 Excel 表格”。我们要用它来存评论数据。

2.1 注册账号#

  1. 打开 supabase.com
  2. 点击右上角 Sign in,选择 Continue with GitHub,用你的 GitHub 账号登录

2.2 创建项目#

  1. 登录后会进入 Dashboard 页面
  2. 点击黄色按钮 New project
  3. 填写以下信息:
字段填什么说明
Name随便填,比如 my-blog-comment只是给你自己看的项目名
Database Password自己设定一个密码,记下来!后面部署 Waline 时要用。建议用 12 位以上,不要包含 @ : / % 这些特殊字符
Region选离你近的亚洲用户选 Northeast Asia(东京)或 Southeast Asia(新加坡)
Pricing PlanFree免费版:500MB 存储 + 每月 5GB 流量,个人博客完全够
  1. 页面上有一个勾选框 “Enable automatic RLS”不要勾选

RLS 是什么? 全称 Row Level Security(行级安全),是数据库的一种权限控制功能。比如”用户 A 只能看到自己的订单,不能看用户 B 的”。你的博客不需要这个——所有评论都是公开的,Waline 自己会管理读写权限。如果勾上了,Waline 访问数据库可能被拦截。

  1. 点击 Create project,等 1-2 分钟初始化

2.3 找到连接信息#

项目创建完成后,我们需要拿到”仓库的钥匙”——数据库连接信息。

  1. 左侧菜单点击 Settings(齿轮图标)
  2. 在 Settings 子菜单中点击 Database
  3. 往下滚动,找到 Connection string 这一栏
  4. 你会看到一串字符:
postgresql://postgres:[YOUR-PASSWORD]@db.xxxxx.supabase.co:5432/postgres
plaintext

把它拆开来看,每一部分都有含义:

postgresql://   协议名,不用管
postgres        用户名(Supabase 默认就是 postgres)
[YOUR-PASSWORD] 你刚才设定的数据库密码(这里显示为占位符)
@               分隔符
db.xxxxx.supabase.co  数据库的地址(xxxxx 是你的项目 ID)
:5432           端口号(5432 是 PostgreSQL 的默认端口)
/postgres       数据库名(Supabase 默认创建一个叫 postgres 的库)
plaintext

现在只要知道这些信息存在这里就行,后面填环境变量时会逐一用到。

三、第二步:在 Vercel 部署 Waline 后端#

Vercel 是一个托管平台,可以免费运行小型后端服务。我们现在要把 Waline 的”仓库管理员”部署上去。

3.1 什么是 Waline 后端?#

一句话解释:Waline 后端就是一段 JavaScript 代码,它做的事情很简单:

  • 收到”获取这篇文章的评论”的请求 → 去数据库查 → 返回评论列表
  • 收到”发表一条新评论”的请求 → 检查内容 → 写入数据库
  • 收到”获取浏览量”的请求 → 查数据库 → 返回数字
  • 提供管理后台 /ui,让你能删评论、审核留言

这段代码需要在一个能 24 小时运行的地方执行——Vercel 的 Serverless Function 就是干这个的。

3.2 开始部署#

重要提示:Waline 的代码仓库(repository)是一个包含多个子项目的大仓库。如果直接克隆整个仓库部署,会导致各种配置问题。Waline 官方已经把 Vercel 部署所需的代码单独放在 example 目录里了。

  1. 打开这个链接(这是关键,不能错):
https://vercel.com/new/clone?repository-url=https://github.com/walinejs/waline/tree/main/example
plaintext

如果你直接去 Vercel 新建项目然后输入 https://github.com/walinejs/waline(不带 /tree/main/example),会导致部署失败。因为 Vercel 会尝试构建整个 Waline 仓库,而这个仓库是一个包含 admin、api、client 等多个子项目的 monorepo(一个代码仓库包含多个独立子项目),根目录没有可以直接部署的输出文件。

  1. Vercel 会让你用 GitHub 登录授权
  2. 登录后会进入项目配置页面:
设置项操作
Framework Preset不用管,默认的 Vite 就行
Root Directory保持默认(Vercel 已自动识别为 example
Environment Variables这是重点,见下一节

3.3 填写环境变量#

环境变量就是告诉 Waline “你的仓库在哪里、钥匙是什么”的配置信息。Waline 启动时会读取这些变量,用来连接数据库。

在 Environment Variables 区域,点 Add 逐个添加以下变量:


第一组:数据库连接信息(必填)

变量名从哪里来
PG_DBpostgresSupabase 默认的数据库名
PG_USERpostgresSupabase 默认用户名
PG_PASSWORD你的数据库密码创建 Supabase 项目时你设定的那个密码
PG_HOSTdb.xxxxx.supabase.co从 Supabase 连接字符串 @ 后面 :5432 前面复制
PG_PORT5432PostgreSQL 默认端口
PG_SSLtrue必须开,Supabase 强制加密连接

第二组:站点信息

变量名说明
SITE_NAME你的博客名在 Waline 管理后台顶部显示
SITE_URLhttps://你的博客域名用于安全域名校验

填好 8 个变量后,点击 Deploy,等待约 2 分钟。

3.4 第一次部署大概率会失败#

等你看到部署结果,很大概率是这样的:

500: getaddrinfo ENOTFOUND db.xxxxx.supabase.co
plaintext

别慌,这是预料之中的。我们来排查。

为什么会失败?#

打开终端(或 PowerShell),执行:

nslookup db.xxxxx.supabase.co
bash

(把 xxxxx 换成你的 Supabase 项目 ID)

你会看到结果里只有 AAAA 记录(IPv6 地址),没有 A 记录(IPv4 地址)

这意味着:Supabase 免费版的数据库地址只支持 IPv6。但 Vercel 的服务器不支持 IPv6 出站连接。 两边协议对不上,就像你拿 Type-C 的线去插 USB-A 的口——物理上不匹配。

这不是你配置错了,是两个平台的设计限制叠加了。

解决方案:使用 Supabase 的连接池(Pooler)#

Supabase 提供了一个免费的”翻译官”——Shared Pooler。它可以把 IPv4 的请求转成 IPv6,帮你桥接 Vercel 和数据库。

操作步骤:

  1. 回到 Supabase 后台 → SettingsDatabase
  2. 找到 Connection string,旁边有一个下拉框
  3. Direct connection 切换到 Session pooler
  4. 连接字符串会变化,新格式如下:
postgresql://postgres.xxxxx:[你的密码]@aws-0-ap-northeast-1.pooler.supabase.com:5432/postgres
plaintext

注意三个变化:

项目直连(失败)Pooler(有效)
主机名db.xxxxx.supabase.coaws-0-xxx.pooler.supabase.com
用户名postgrespostgres.xxxxx
IPv4 支持❌ 只有 IPv6✅ 有 IPv4
  1. 回到 Vercel,更新 Environment Variables:
变量新值
PG_HOSTaws-0-xxx.pooler.supabase.com(从新连接字符串复制)
PG_USERpostgres.xxxxx(从新连接字符串复制)
PG_PORT5432(不变)

端口说明:Pooler 有两个端口可用。5432 是 Session 模式(一个用户会话期间保持同一连接),6543 是 Transaction 模式(每次数据库操作完就断开)。两者的区别后面会讲到。

  1. 去 Deployments 页面,点上次部署右侧的三个点 Redeploy

这一次,部署应该成功了。但访问 Waline 地址可能会看到新的错误:

500: relation "wl_users" does not exist
plaintext

3.5 第二次部署也大概率会失败#

这次的错误信息变了,这说明数据库已经连上了(否则报的是连接错误),但 Waline 需要的”表格”不存在。

什么是”表”?#

数据库里,数据是按”表”来组织的。你可以把表理解为 Excel 里的一个 Sheet:

表名存什么类比
wl_comment所有评论Excel 的”评论”Sheet
wl_counter所有浏览量和点赞数Excel 的”统计”Sheet
wl_users管理员账号Excel 的”用户”Sheet

Waline 首次启动时会自动创建这些表(相当于新建 Excel Sheet 并设置好表头)。但现在表没有被创建——因为 Pooler 不支持这种”建表”操作。

为什么 Pooler 不能建表?#

Pooler 底层用的是 PgBouncer(PostgreSQL 的连接池中间件)。把它想象成一个前台:

  • 普通操作(查评论、写评论、更新点赞数)→ 前台转交给后台,正常处理 ✅
  • 建表操作(CREATE TABLE)→ 这是”重新装修”级别的工程,前台拦下来不让通过 ❌

这不分 Session 模式还是 Transaction 模式——只要走 Pooler,建表(SQL 术语叫 DDL)就可能被拦截。

解决方案:在 Supabase 后台手动建表#

Pooler 不让建,我们就绕过它——在 Supabase 自己的后台直接操作数据库(后台走的是直连,不受 Pooler 限制)。

  1. Supabase 后台 → 左侧菜单 SQL Editor
  2. 点击 New query(新建查询)
  3. 把下面这段 SQL 全部复制粘贴进去:

这段 SQL 是什么意思?CREATE TABLE 就是”新建一张表”,后面的括号里是表的列定义(相当于 Excel 的表头)。int 是整数、varchar(255) 是文本(最多 255 个字符)、timestamp 是时间。PRIMARY KEY 是主键——每条数据的唯一编号。

  1. 点击右下角的 Run 执行

  2. 执行时会弹出一个警告:“This query creates tables without enabling Row Level Security…” → 点击 Run 继续,不用管(第二节已经解释过,Waline 不需要 RLS)

  3. 看到 “Success” 提示后,回到 Vercel → Deployments → 再次 Redeploy

这次部署应该成功了!

四、第三步:注册管理员账号#

部署成功后,你获得了 Waline 后端的地址,类似:

https://你的项目名-git-main-你的用户名.vercel.app
plaintext

4.1 设置管理员密码#

  1. 浏览器打开 https://你的waline地址.vercel.app/ui
  2. 第一次访问会进入注册页面
  3. 设定一个管理员密码,记好
  4. 注册成功后,你就进入了 Waline 管理后台

4.2 管理后台能做什么#

  • 📝 评论管理:查看所有评论,可以通过、删除、标记为垃圾
  • 📊 数据查看:每篇文章的浏览量和评论数
  • 👤 用户管理:封禁恶意用户
  • 🔔 通知设置:配置新评论的邮件/微信通知(可选)

五、第四步:打开前端开关#

后端已经就绪。现在让前端(你的博客)知道该去哪里找 Waline。

5.1 启用 Waline#

编辑 src/site.config.ts,找到这一段:

waline: {
  enable: false
}
ts

改成:

waline: {
  enable: true,
  server: 'https://你的waline地址.vercel.app',
  additionalConfigs: {
    pageview: true,
    comment: true
  }
}
ts
字段含义
enable: true打开 Waline 功能的总开关
serverWaline 后端的地址(告诉前端去这里找 API)
pageview: true启用浏览量统计
comment: true启用评论计数显示

5.2 修复站点 URL#

astro.config.ts 里有一个 site 字段,它影响 RSS、sitemap 等功能的 URL 生成。如果你的站点域名已经换了,需要同步更新:

site: 'https://你的实际域名',
ts

5.3 默认开启评论功能#

src/content.config.ts 中,comment 字段的默认值是 false——这意味着每篇新文章都需要手动在 frontmatter 里加 comment: true 才会显示评论区。

把默认值改成 true,所有文章自动生效:

// 改之前
comment: z.boolean().default(false),

// 改之后
comment: z.boolean().default(true),
ts

5.4 部署前端#

构建、推送、部署到 Netlify。访问你的博客,随便点开一篇文章,滑到底部——你应该能看到 Waline 评论区了。文章标题下方会显示”X views · Y comments”。

六、你踩过的坑我都替你踩过了#

序号为什么会遇到怎么解决
1Vercel 部署失败,找不到 dist克隆了整个 monorepo 仓库使用 tree/main/example 后缀的模板链接
2环境变量填了但连不上数据库旧教程用的 LEAN_* 前缀是 LeanCloud 的,Supabase 要用 PG_*改用 PG_DBPG_USER 等变量
3ENOTFOUND db.xxx.supabase.coSupabase 免费版数据库只有 IPv6,Vercel 不支持 IPv6改用 Shared Pooler(有 IPv4 地址)
4relation "wl_users" does not existPooler(PgBouncer)拦截建表 DDL 语句在 Supabase SQL Editor 手动执行建表 SQL
5数据库密码含 @ 等特殊字符连接字符串中 @ 是分隔符,密码里有会截断把密码改成不含特殊字符的

每个坑的原因都可以归结为一句话:不同平台之间的兼容性假设不一致。Supabase 假设你的后端能连 IPv6,Vercel 假设你的数据库有 IPv4。PgBouncer 假设你不会通过它来建表。这些假设写在各自的文档角落里,不踩一遍根本不知道。

七、费用的最后确认#

全程零费用:

服务免费额度够用吗
Supabase500MB 数据库 + 5GB/月流量个人博客几年用不完
Vercel100GB/月带宽 + 1000 次/天函数调用完全够用
Netlify100GB/月带宽静态站点够了

你唯一需要付出的,就是这篇文章里踩坑的时间——但现在你已经看过了,照着操作 30 分钟搞定。

手把手教你搭建 Waline 评论系统:从零到上线,踩坑全记录
https://glinfei.space/blog/2026-07-28-waline-setup
Author 甘霖飞
Published at 2026年7月28日
Comment seems to stuck. Try to refresh?✨