给静态博客(Hugo / Hexo / VuePress 等)接入评论系统时,Twikoo 是一个非常轻量、好看、易用的选择。官方推荐的部署方式有 Vercel、腾讯云 CloudBase 等,但如果你已经有一台自己的服务器并安装了宝塔面板,其实可以完全私有部署,数据 100% 在自己手里,也不受海外网络波动影响。 官方也有开始入门教程
本文记录一次从零开始,在宝塔面板上部署 Twikoo 后端服务,并接入到 Hugo 博客的完整过程。
一、准备工作
- 一台已安装宝塔面板的 Linux 服务器(本文使用 CentOS 7 + 宝塔 7.x)
- 服务器公网 IP 一个,或已备案的域名一个(可选,若使用国内厂商服务器,绑定域名需完成 ICP 备案 + 厂商接入备案),我自己使用的是阿里云的服务器,也是从阿里云买的域名。其实不建议选择.cn 的域名,因为备案太久了,所以不建议使用(因为我买的.cn 域名备案时间太长了)。
- 已完成 ICP 备案的域名一个(可选,不用域名也能跑起来)
二、安装依赖
在宝塔"软件商店"中依次安装以下软件:
| 软件 | 说明 |
|---|---|
| Node.js 版本管理器 | 用于运行 Twikoo 服务,安装 Node.js 18.x(推荐) |
| MongoDB | Twikoo 的数据存储,安装 4.x 或 5.x 均可 |
| PM2 管理器 | 用来守护 Node 进程 |
| Nginx | 反向代理(宝塔默认已装) |

Node.js 安装完成后,进入 Node.js 版本管理器 → 版本管理,把某个版本设为默认,然后重开终端确认:
| |
若在 SSH 中 npm: command not found,可以做个软链:
| |
三、创建 MongoDB 数据库
宝塔 → 数据库 → MongoDB → 添加数据库:
- 数据库名:
twikoo - 添加至:本地服务器 (127.0.0.1)
因为 MongoDB 默认只监听 127.0.0.1,外网连不到,同一台服务器上的 Twikoo 直接连即可,可以不开启认证。连接串是:
| |
如果要开启密码认证,需要在 MongoDB 配置里设置
security.authorization: enabled,然后重启服务,再回到宝塔数据库列表点"改密"。本文选择本机不认证的方式,简单省事。
四、部署 tkserver
Twikoo 的私有部署包名叫 tkserver,直接用 npm 安装。
| |
安装完成后,先看一下入口文件:
| |
新版 tkserver(本文时 1.7.14)的入口是 server.js,本身就是一个完整的启动脚本,会读取 MONGODB_URI、TWIKOO_PORT 等环境变量后自启监听。所以我们不需要再包一层 index.js,直接用 PM2 拉起它即可。
五、用 PM2 启动 Twikoo
| |
查看运行状态:
| |
日志中应该能看到:
| |
本地验证:
| |
期望返回:
| |
如果没起来,多半是以下几种情况:
- Node 版本过低(低于 16),升级即可
- 忘了
cd /www/wwwroot/twikoo就装的包,导致node_modules装在别处 - MongoDB 服务没启动,
systemctl status mongod查看
六、开放端口
curl http://127.0.0.1:8080 通了,不代表公网就通了。要让外部能访问,需要三层放行:
1. 阿里云 / 腾讯云安全组
在云控制台的实例安全组入方向规则中,放行 TCP 8080。这一步最容易被忽略,也是最常见的踩坑点。

2. 宝塔面板安全
宝塔 → 安全 → 添加放行端口 8080。

3. 系统防火墙 firewalld
在服务器上执行:
| |
如果没看到 8080/tcp,执行:
| |
三层都放行后,浏览器打开 http://你的公网IP:8080,看到 Twikoo 的 JSON 就成功了。
| |
七、(可选)绑定域名 + 反向代理
如果只用 IP + 端口方式使用,可以跳过本节。但如果你的博客是 HTTPS 站点,浏览器会拦截 HTTP 的 Twikoo 请求(混合内容),所以建议绑定域名并配置 HTTPS。
1. 域名解析
在你的域名 DNS 控制台点击解析设置,添加一条 A 记录:
| 类型 | 主机记录 | 记录值 |
|---|---|---|
| A | twikoo | 你的服务器公网 IP |
2. 阿里云接入备案(国内服务器必做)
如果服务器在国内(如阿里云),即便主域名已经 ICP 备案,新添加的子域名仍需要在服务器厂商侧完成"接入备案"。否则访问会被厂商网关拦截,页面提示 “该域名当前备案状态不符合访问要求”。
- 阿里云:控制台 → 备案 → 新增接入
- 腾讯云:控制台 → 网站备案 → 补充备案
审核大概 1~3 个工作日。若急用,可以先按第六节的 IP + 端口方式使用。
3. 宝塔添加站点
宝塔 → 网站 → 添加站点:
- 域名:
twikoo.example.com - PHP 版本:纯静态
4. 反向代理
打开该站点 → 设置 → 反向代理 → 添加:
- 目标 URL:
http://127.0.0.1:8080 - 发送域名:
$host
5. SSL 证书
站点设置 → SSL → Let’s Encrypt,勾选域名一键申请,成功后开启"强制 HTTPS"。(建议去阿里云做这个)
6. 验证
浏览器打开 https://twikoo.example.com,看到 Twikoo 的 JSON 即可。
八、Hugo 博客接入
以 hugo-theme-stack 主题为例(主题内置了 Twikoo 支持)。修改 config/_default/params.toml:
| |
envId 填的就是你上面得到的地址:
- 使用域名:
https://twikoo.example.com - 使用 IP:
http://47.x.x.x:8080
region 只有腾讯云 CloudBase 部署时需要填,私有部署留空即可。
本地预览:
| |
打开任一文章页拉到底部,能看到 Twikoo 评论框就成功了。首次访问会提示设置管理员密码,设置好后点击评论框右上角齿轮图标即可进入后台,管理评论、配置邮箱通知、开启防垃圾评论等。
九、常见问题
Q: curl http://127.0.0.1:8080 能通,但外网 IP:8080 无法访问
99% 是端口没放行。按第六节逐层排查(云安全组 → 宝塔安全 → firewalld)。
Q: 浏览器控制台报 Mixed Content 错误
博客是 HTTPS 但 Twikoo 是 HTTP。要么给博客降级为 HTTP(不推荐),要么给 Twikoo 上 HTTPS(第七节)。
Q: PM2 状态一直是 errored
pm2 logs twikoo --lines 50 --nostream 看具体报错。常见的是入口文件路径写错,或 Node 版本过低。
Q: 评论无法发出,一直转圈
- 前端 F12 打开控制台看请求是否 500 / CORS 报错
- 检查 Twikoo 后端能否连上 MongoDB(
pm2 logs twikoo)
十、参考资料
至此,一个完全属于自己的评论系统就搭好了。数据在自己手里,速度也不错,唯一缺点就是要自己扛服务器稳定性 ——不过既然都自建博客了,这点应该也是乐趣的一部分吧。
