博客是基于 Hexo 搭建的,主题使用的是,想要给文章添加评论功能,以下是 butterfly 文档中展示的支持的评论插件汇总

这一堆评论插件里面,我是只尝试了 Gitalk 和 Artalk。其他的插件像 Disqus 是国外的,国内访问可能会有点问题,据说免费版本的还有广告?

一、对 Gitalk 的尝试

Gitalk 是基于 Github issues 的评论插件,但好像有安全性问题,需要申请 Github OAuth Applications,通过 OAuth 取得操作 issues 的权限。配置中需要将 client ID 和 client Secret 硬编码入 commit,这个操作可能会将两者直接暴露出去。

其实我在尝试 Gitalk 时也没有真正地部署成功,遇到了好多问题,尤其是 issues ID 和博客页面绑定的时候,弄不好。虽然已经实现的通过 issues lable 和博客页面进行绑定,但是感觉有点繁琐。而且好像需要给每个博客页面都新建一条 issues,对,好像是手动新建,要真是这样的话,就太繁琐了,不仅需要维护博客文件,还需要再去 github 上面维护 issues。

还有就是博客使用 Gitalk 时,如果想要去评论,是需要用户进行登陆的,即用户需要登陆自己的 github 之后,才能在博客文章里进行评论。

总之,最后没有选择使用 Gitalk

二、Hexo + butterfly + Artalk

Artalk 是需要在服务器上进行部署的。正好可以将其与博客部署到同一个阿里云 ECS,系统资源是够够的。

1、Artalk 简介

Artalk  是一款简洁的自托管评论系统,你可以在服务器上轻松部署并置入前端页面中。

来到你的博客,或是任意位置,放置 Artalk 评论框,让页面具备丰富的社会化功能。

官网简介:👋 Hello Friend | Artalk

1.1 功能亮点

  • 轻量设计

    • 前端采用 TypeScript (Vanilla JS),轻量级,无冗余依赖,仅 ~30KB (gzipped)。
    • 后端采用 Golang 重制 (Artalk v2),跨平台,体积小巧,五脏俱全,快速部署。
  • “麻雀虽小,五脏俱全”

    • Markdown 语法 + 代码高亮
    • 通知中心 - 站内:侧边栏 + 红点标记
    • 多形式推送 - 站外:邮件、TG、钉钉、飞书 + 异步执行
    • 评论审核:折叠 / 反垃圾 / 频率限制 / 滑动验证
    • 多站点:共用同一个后端程序,多站点集中化管理
    • 表情包:支持 OwO 格式 + 动态加载
    • Artrans:评论数据快速迁移 (导入 / 导出) 工具
    • 评论投票 / 身份徽章 / 密码验证 / 说说模式
    • 评论盖楼 / 评论分页 / 滚动加载 / 实时预览
    • 评论排序 / 评论置顶 / 评论防丢 / 自动填充
    • 图片上传 / 页面管理 / 站点隔离 / 夜间模式
  • “Unlimited Blade Works”

    • Artalk 正在持续成长,创意由你发挥,价值由你赋予!
    • 不论是 Vue、React、Svelte 的前端项目,还是 WordPress、Typecho、Hexo 等博客系统,都可以快速引入 Artalk,结合诸位的聪明才智,我们相信 Artalk 能够自如应对各种业务场景。

2、Artalk 部署

我选择的是将 Artalk 部署到 docker 中,官方文档里也有具体的步骤。请参阅:📦 程序部署 | Artalk

2.1 阿里云 ECS 安装 docker

阿里云 ECS 使用的系统镜像是 alibaba cloud linux,通过 dnf 命令(包管理器)进行安装。

添加 docker-ce 的 dnf 源。

1
$ dnf config-manager --add-repo=https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 alibaba cloud linux 专用的 dnf 源兼容插件。

1
$ dnf -y install dnf-plugin-releasever-adapter --repo alinux3-plus

安装 docker-ce,安装后通过 docker version 命令进行验证

1
2
3
$ dnf -y install docker-ce
$ docker -v
Docker version 25.0.2, build 29cf629

启用 docker 服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ systemctl start docker
$ systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2024-02-02 11:18:03 CST; 4h 2min ago
Docs: https://docs.docker.com
Main PID: 100929 (dockerd)
Tasks: 24
Memory: 123.9M
CGroup: /system.slice/docker.service
├─100929 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
├─106666 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.2 -container-port 23366
└─106671 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 8080 -container-ip 172.17.0.2 -container-port 23366

2.2 在 docker 中部署 Artalk

拉取 Artalk 镜像。

1
$ docker pull artalk/artalk-go

根据镜像运行 Artalk 实例。

1
2
3
4
5
6
$ docker container run -d \
--name artalk \
-p 8080:23366 \
-v $(pwd)/data:/data \
--restart=always \
artalk/artalk-go

查看容器运行情况。

1
2
3
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ba2a4aa82c6 artalk/artalk-go "/entrypoint.sh serv…" 2 hours ago Up 2 hours 0.0.0.0:8080->23366/tcp, :::8080->23366/tcp artalk

上面的命令将服务器的 8080 端口与刚启动的 Artalk 容器的 23366 端口进行映射,需要在阿里云 ECS 服务器的网络安全组中增加 8080 端口的访问规则。

只有执行命令创建管理员账户

1
$ docker exec -it artalk artalk admin

部署好之后通过阿里云 ECS 的 IP 加端口访问 Artalk 后台管理系统。

部署成功。

2.3 修改 butterfly 配置

修改 butterfly 主题配置文件 _config.butterfly.yml 中的配置。

1
2
3
4
comments:
# Up to two comments system, the first will be shown as default
# Choose: Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk
use: Artalk

启用评论插件且指定为 Artalk。

1
2
3
4
5
artalk:
server: http://111.111.111.111:8080
site: zhuo的个人博客
visitor: false
option:

修改 artalk.server 变量,对应阿里云 ECS 上面部署的 Artalk 服务地址。

之后重新部署博客即可。

1
$ hexo clean && hexo g && hexo d

博客部署成功之后,按理说是没什么问题的了,但是,理想很美好,现实很骨感,肯定会出各种各样的问题。

3、部署后阻碍问题汇总

3.1 评论服务接口调用失败

在博客点击进入文章内容页面时,会调用两个接口 confpv,这两个接口都有一个症状,请求失败,具体失败原因可以从控制台中查看。

如上图所示,提示中已经给出了失败原因:

The page at …… over HTTPS, but requested an insecure resource …… This request has been blocked; the content must be served over.

意思是说,博客页面启用了 HTTPS,但是在调用评论后端服务的 API 时使用的是 HTTP,所以请求阻塞了。

3.1.1 问题分析

上面说了是因为调用评论后端 API 时使用的是 HTTP,所以需要改为 HTTPS。

我现在使用的 SSL 证书是阿里云 3 个月的免费版本的,该证书是没有办法在 IP 上使用的,只能用在域名上。要想通过 HTTPS 调用评论 API,就需要将原来的 IP 访问改为域名访问。

z2huo.cn 域名下新增了子域名 artalk.z2huo.cn 的 DNS 解析用于 Artalk 评论服务。

同时,需要在阿里云的 SSL 证书控制台中给子域名申请免费的 SSL 证书。并将该 SSL 证书部署到 ECS 服务器上。可以参考:阿里云网站配置 SSL 证书启用 HTTPS

3.1.2 具体解决步骤

之后关于端口的问题,可以选择监听默认的 443 端口,匹配到对应的 URL 请求之后,将请求转发给 8080 端口的评论后端服务。nginx 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name artalk.z2huo.cn;

ssl_certificate "/etc/nginx/conf.d/cert/artalk.z2huo.cn.pem";
ssl_certificate_key "/etc/nginx/conf.d/cert/artalk.z2huo.cn.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;

location ~ ^/api/.* {
proxy_redirect off;
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_pass http://localhost:8080;
}
}

因为上面提到的评论 confpv 接口都是以 /api/ 开头的,所以应该是暴露给前端的所有 api 接口都是以 /api/ 开头的,所以上面 nginx 配置中,将 443 端口监听到的以 /api/ 开头的请求都转发给 8080 端口的评论后端服务。

注意上面监听的是 443 端口,而该端口同时也是博客部署的端口,所以如果博客中有其他 API 与 Artalk 评论的 API 有冲突,就不能同时使用 443 端口了。

后续补充 2024-02-04:还是不要使用 /api/ 的路径了,因为发现这个评论插件不止是增删改查的 API,还有侧边栏,这个侧边栏里面还有好多接口,而且还有静态页面,所以这个 /api/ 有很大的限制。而使用与博客相同的 443,不知道是否会产生冲突,所以还是老老实实用 https://artalk.z2huo.cn:8081 吧。

同时,butterfly 配置文件 _config.butterfly.yml 如下。

1
2
3
4
5
artalk:
server: https://artalk.z2huo.cn
site: zhuo的个人博客
visitor: false
option:

但是我没有选择使用 443 接口。考虑到是 Altart 版本更迭造成的 api 更新和 API 接口潜在的冲突问题。版本变更问题参考:[[Hexo 评论插件#3.2 评论服务接口404]]。

所以我是监听的 8081 端口,将所有 8081 端口的请求都转发给 8080 端口的评论后端服务。对应的 nginx 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 8081 ssl http2;
listen [::]:8081 ssl http2;
server_name artalk.z2huo.cn;

ssl_certificate "/etc/nginx/conf.d/cert/artalk.z2huo.cn.pem";
ssl_certificate_key "/etc/nginx/conf.d/cert/artalk.z2huo.cn.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;

location / {
proxy_redirect off;
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_pass http://localhost:8080;
}
}

同时,butterfly 配置文件_config.butterfly.yml如下。

1
2
3
4
5
artalk:
server: https://artalk.z2huo.cn:8081
site: zhuo的个人博客
visitor: false
option:

之后,重新部署博客到服务器后,浏览器控制台中文章页面对于 confpv 接口的访问应该就没有问题了。如果没有下面的问题的话。

3.2 评论服务接口 404

哈哈,问题总是一个接着一个的。

先是解决了上面的 HTTPS 的问题,部署成功之后,发现接口 404 了。即评论服务没有接口。

原因是版本不匹配。即前端 js 文件的版本和后端服务的版本不匹配。

3.2.1 问题分析

从浏览器中看到的 js 版本是 V2.7.3,然后最新的版本是 V2.8.0。两个版本不对应,所以接口就 404 了。

所以就有两个方案:

  • docker 中不拉取最新版本的镜像,最新版本为 V2.8.0,重新拉取 V2.7.3 版本的镜像,运行旧版本容器
  • 将 butterfly 主题中的 Altalk JS 文件版本进行更新
3.2.2 运行旧版本的后端服务

拉取旧版本的 docker 镜像。

1
$ docker pull artalk/artalk-go:2.7.3

运行旧版本的服务。

1
2
3
4
5
6
$docker container run -d \
--name artalk_2.7.3 \
-p 8080:23366 \
-v $(pwd)/data:/data \
--restart=always \
artalk/artalk-go:2.7.3

上面新增管理员用户的命令也要重新执行一遍。

1
$ docker exec -it artalk_2.7.3 artalk admin

新服务重启好之后,博客前端中调用评论服务的端口可以正常访问通过的。

3.2.3 更新 butterfly 主题中 Altalk 文件版本

首先下载最新版本的 Artalk 依赖包。

1
$ cnpm install artalk

之后需要修改 butterfly 以插件配置文件,来表示该 js 是 V2.8.0 版本的 js 文件。我这里有两个文件:

  • ~/hexo-blog/node_modules/hexo-theme-butterfly/plugins.yml
  • ~/hexo-blog/node_modules/hexo-butterfly-extjs/plugins.yml

第一个文件是 butterfly 的依赖,第二个依赖是后面单独下载的插件(不使用主题提供的 CDN 文件时需要将依赖文件都下载到本地)。两个配置文件中都有关于 js 和 css 版本的声明,修改为 V2.8.0 版本即可:

1
2
3
4
5
6
7
8
artalk_js:
name: artalk
file: dist/Artalk.js
version: 2.8.0
artalk_css:
name: artalk
file: dist/Artalk.css
version: 2.8.0

之后执行 hexo 命令重新部署博客到服务器上即可。

可以看到在 V2.8.0 版本接口 API 发生了变更,现在是 /api/v2/pages/pv,之前的 V2.7.3 版本是 /api/pv

3.3 文章页面显示未找到站点

上面遇到的问题都解决之后,评论服务 API 可以访问成功,但是页面显示如下:

原因是 butterfly 配置和 Artalk 管理系统中站点名称不一致。如下是 butterfly 中的配置:

1
2
3
4
5
artalk:
server: https://artalk.z2huo.cn:8081
site: zhuo的个人博客
visitor: false
option:

下图是站点配置。

将两个名称改为相同的即可。都改为 z2huo的个人博客

3.4 不想让别人通过 ECS 公网 IP 访问

既然已经配置了域名,且配置了免费的阿里云 SSL 证书启用了 HTTPS,就不能让别人通过公网 ip 对网站进行访问了,可以在 nginx 中添加如下配置:

1
2
3
4
5
6
7
8
9
server {
listen 8081 ssl http2;
listen [::]:8081 ssl http2;
server_name artalk.z2huo.cn;

if ($host != $server_name) {
return 403;
}
}

artalk.z2huo.cn 的 nginx 配置中,添加上述 if 判断代码,这样当访问者访问 8081 端口但不是 artalk.z2huo.cn 域名时,页面返回状态码 403

三、评论效果演示

okk,到现在算是进展到一定阶段了。下面是界面展示。

博客文章页面评论
Artalk后台评论一览

四、对 Artalk 进一步的设置

相关链接

Butterfly 安裝文檔(四) 主題配置-2 | Butterfly

Artalk | 自托管评论系统

z2huo - 个人博客

Linux Command dnf 软件包管理-阿里云开发者社区 (aliyun.com)

使用 docker-ce、epel 等第三方 DNF(YUM)源安装软件失败怎么办-阿里云帮助中心 (aliyun.com)

artalk/artalk-go - Docker Image

OB tags

#阿里云 #Hexo #Nginx #HTTPS #Docker