大家好,今天我为我的博客添加了 Waline 评论功能,写下这篇文章既是分享也是记录,欢迎大家留言评论。
在网站中添加评论系统可以增强与用户的互动,评论是个相对低频的操作,自行开发一套评论系统投入的成本相对较高,而且很多静态网站也难以适用。Waline 是一款轻量、快速且功能丰富的评论系统,支持私有部署。由于官方文档对于 MySQL+Self Host 的介绍过于简单且稍显混乱,因此,本文将详细介绍如何在私有服务器上使用 MySQL 数据库独立部署 Waline 服务端。
首先,在你的服务器上创建一个用于存放 Waline 服务端代码的目录:
mkdir waline-server
cd waline-server
在项目目录下安装 Waline 的服务端模块。确保你的服务器上已经安装了 Node.js 和 npm,如果还没有,可以先安装它们。
npm install @waline/vercel
安装过程中你可能需要安装或升级你服务器上的 Node.js 和 npm,点击这里查看相关教程。
默认你已经在服务器上安装运行了 MySQL。
在 MySQL 中创建一个名为 waline
的数据库,并导入 Waline 提供的 SQL 文件以初始化数据库结构。
mysql -uroot -p
CREATE DATABASE waline;
exit
# 导入数据库结构
mysql -uroot -p waline < /path/to/waline.sql
提示: 你可以从 GitHub 下载 Waline 的 SQL 文件。
数据库优化建议:Waline 的数据库表是没有建索引的,如果你对性能有考虑可以为 url 字段加索引:
为统计计数表 url 字段加前缀索引:
CREATE INDEX idx_url_prefix ON wl_Counter(url(128));
为评论表 url 字段加前缀索引:
CREATE INDEX idx_url_prefix ON wl_Comment(url(128));
在项目根目录下创建 .env
文件,并根据你的服务器环境设置以下变量:
### 数据库
# 数据库连接地址
MYSQL_HOST="127.0.0.1"
# 数据库连接端口号
MYSQL_PORT=3306
# 数据库名
MYSQL_DB="waline"
# 连接数据库用户名
MYSQL_USER="your_db_username"
# 连接密码
MYSQL_PASSWORD="your_db_password"
### 安全
# 基于 IP 的评论发布频率限制,单位为秒。设置为 0 不限制
IPQPS=60
# 评论发布审核开关。开启后评论需要经过管理员审核后才能显示,所以建议在评论框默认文字上提供提示
COMMENT_AUDIT=true
# 违禁词配置,包含违禁词的内容会直接标记为垃圾评论。
FORBIDDEN_WORDS=""
# 安全域名,配置后非该域名来源的请求会返回 403 状态码。支持字符串、正则、数组类型,不配置表示允许所有域名来源。
SECURE_DOMAINS=""
### 高级配置
# 评论成功后会向 WEBHOOK 配置的地址发送一条 POST 请求
WEBHOOK="http://127.0.0.1:1988/my-waline-webhook"
其他配置可以看官方服务端配置文档。
WEBHOOK 配置用于评论通知,需要你有自己的 webhook 接口。Waline 还支持其他通知方式,详情参考官方评论通知文档。
为 Waline 服务端创建一个启动脚本 main.js
,并使用 dotenv
模块加载环境变量。
首先,安装 dotenv
模块:
接着,在项目根目录下创建 main.js
文件:
// 引入dotenv
const dotenv = require("dotenv");
// 加载环境变量
dotenv.config();
// 引入并执行 Waline 服务端代码
require("@waline/vercel/vanilla.js");
完成启动脚本的编写后,可以使用 node /path/to/main.js
命令启动服务测试是否成功。
服务运行后,通过访问 http://host:port
可以看到一个评论输入框页面。默认端口是 8360
,服务器上可以通过公网 IP 使用端口进行访问。
最好不要暴露端口到外部,建议将 host 绑定为 localhost,修改 host 和 port 需要修改服务端代码。
在你的项目根目录打开 node_modules/@waline/vercel/vanilla.js
:
const path = require('node:path');
const Application = require('thinkjs');
const instance = new Application({
ROOT_PATH: __dirname,
APP_PATH: path.join(__dirname, 'src'),
proxy: true, // use proxy
env: 'production',
});
instance.run();
let config = {
host: "127.0.0.1", // 设置host
port: 8360, // 设置服务端口
};
try {
config = require('./config.js');
} catch {
// do nothing
}
for (const k in config) {
think.config(k, config[k]);
}
在 config
中通过 host
和 port
字段自定义运行 host 和端口。
thinkjs 的配置字段请参考这里。
为了确保 Waline 服务在服务器重启后自动启动,并在发生异常时自动恢复,你可以使用 pm2
或 supervisor
来守护这个进程。
以 pm2
为例:
npm install -g pm2
pm2 start /path/to/main.js --name "waline-server"
pm2 save
pm2 startup
到这里 Waline 服务端就已经作为生成环境的服务稳定运行起来了。
为了能够通过域名访问 Waline 服务,我们可以使用 Nginx 配置反向代理。
编辑你的 Nginx 配置文件,添加以下内容(示例中包含 ssl 证书配置):
upstream waline {
server 127.0.0.1:8360;
keepalive 600;
}
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_session_timeout 30m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header X-Cache $upstream_cache_status;
proxy_pass http://waline/;
}
}
server {
listen 80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}
完成配置后,重启 Nginx,在重启 Nginx 之前,先测试配置文件是否正确,可以使用以下命令:
如果测试通过,再重启 Nginx:
sudo systemctl restart nginx
Waline 部署完成后,访问 https://your-domain.com/ui/register
,第一个注册的用户将被设为管理员。
作为管理员,你可以在管理后台对评论进行审核、删除等操作。
在你的网页中进行如下设置:
导入 Waline 样式 https://unpkg.com/@waline/client@v3/dist/waline.css
。
创建 <script>
标签使用来自 https://unpkg.com/@waline/client@v3/dist/waline.js
的 init()
函数初始化,并传入必要的 el
与 serverURL
选项。
el
选项是 Waline 渲染使用的元素,你可以设置一个字符串形式的 CSS 选择器或者一个 HTMLElement 对象。serverURL
是服务端的地址,即上一步获取到的值。HTML 示例:
<head>
<!-- ... -->
<link
rel="stylesheet"
href="https://unpkg.com/@waline/client@v3/dist/waline.css"
/>
<!-- ... -->
</head>
<body>
<!-- ... -->
<div id="waline"></div>
<script type="module">
import { init } from "https://unpkg.com/@waline/client@v3/dist/waline.js";
const url = new URL(window.location.href);
const path = `${url.origin}${url.pathname}`;
const waline = init({
el: "#waline",
serverURL: "https://waline.axiaoxin.com",
path: path, // 当前文章页路径,用于区分不同的文章页
meta: ["nick"], // 评论者相关属性。
login: "disable", // 禁用登录,用户只能填写信息评论
copyright: false, // 是否显示页脚版权信息:本站评论功能使用 waline 实现!
reaction: [
// 为文章增加表情互动功能,设置为 true 提供默认表情,也可以通过设置表情地址数组来自定义表情图片,最大支持 8 个表情。
"https://npm.elemecdn.com/@waline/[email protected]/bilibili/bb_heart_eyes.png",
"https://npm.elemecdn.com/@waline/[email protected]/bilibili/bb_thumbsup.png",
"https://npm.elemecdn.com/@waline/[email protected]/bilibili/bb_zhoumei.png",
"https://npm.elemecdn.com/@waline/[email protected]/bilibili/bb_grievance.png",
"https://npm.elemecdn.com/@waline/[email protected]/bilibili/bb_dizzy_face.png",
"https://npm.elemecdn.com/@waline/[email protected]/bilibili/bb_slap.png",
],
locale: {
placeholder:
"请注意:提交留言后,内容需审核通过后才会展示,请勿重复发布。",
reaction0: "非常有用",
reaction1: "有帮助",
reaction2: "一般",
reaction3: "无帮助",
reaction4: "看不懂",
reaction5: "有错误",
reactionTitle: "本站内容对你有帮助吗?",
sofa: "还没有人留言哦!快来抢沙发吧~",
comment: "留言",
},
emoji: [
"https://npm.elemecdn.com/@waline/[email protected]/bmoji",
"https://npm.elemecdn.com/@waline/[email protected]/bilibili",
"https://npm.elemecdn.com/@waline/[email protected]/weibo",
],
imageUploader: false, // 自定义图片上传方法。默认行为是将图片 Base 64 编码嵌入,你可以设置为 false 以禁用图片上传功能。
search: false, // 禁用gif表情包搜索
wordLimit: 1024, // 评论字数限制。填入单个数字时为最大字数限制。设置为 0 时无限制。
comment: true, // 文章评论数统计,填入字符串时会作为 CSS 选择器。
pageview: true, // 文章浏览量统计,填入字符串时会作为 CSS 选择器。
});
</script>
</body>
评论服务此时就会在你的网站上成功运行 🎉
点击 https://waline.axiaoxin.com 可查看效果。
至此,你已经成功在私有服务器上使用 MySQL 完成了 Waline 服务端的独立部署以及前端 HTML 网页的客户端集成。
如果你在部署过程中遇到任何问题,欢迎留言讨论!更多 Waline 相关教程请参考这里。