如何搭建个人网页(十)—— 评论系统(二)
开始
本章主要讲如何为个人网站增加评论系统。
上一章搭评论系统用的是 Waline+Leancloud数据库+Vercel服务端 的方案,今天介绍一种 服务器docker + waline + mysql 方案,还是继续用之前买的阿里云ECS服务器。
首先要说明,该方案要比上一章的方案复杂一些,主要是由于要为服务器配置SSL证书,还要求域名备案,好处在于你能对评论数据库和服务端有完全的掌控,请参考选择。
安装docker并拉取所需镜像
进入服务器命令行,下载并安装docker:
1 | curl -fsSL https://get.docker.com -o get-docker.sh |
然后可以进行docker换源,但是总感觉服务器的dockerhub不是最新的,所以我选择了在本地机的docker拉取所需的镜像,然后通过docker save和scp上传到服务器中,再用docker load加载镜像,具体如下(如果你能确保dockerhub能拉到最新的镜像,直接在服务器里运行下面的两个docker pull
命令即可):
在本地机中(确保你本地机安装了docker,并且docker服务已启动):
1 | docker pull mysql:8.0 # 拉取 MySQL8.0 镜像 |
然后在服务器中:
1 | docker load -i mysql.tar # 从tar文件加载 MySQL 镜像 |
别忘了把本地机和服务器里的tar文件删除,以免占用空间。
配置安全组
到阿里云ECS控制台,左侧 网络与安全/安全组,创建一个安全组,入规则方向,手动添加两个规则,协议类型选TCP,端口分别为8360和3306,授权对象为所有ipv4,如下图:
然后选择刚刚创建的安全组,进入实例列表,实例加入安全组,实例选择你的服务器,确定。
部署MySQL数据库
首先创建一个docker卷,用以持久化数据:
1 | docker volume create mysql-data |
使用docker快速部署mysql数据库:
1 | docker run -d --name waline-mysql \ |
输入docker ps -a
查看容器是否运行正常。
然后获取waline.sql,但是官网给的这个sql脚本有语法问题,执行不起来,下面贴个修改后正确的:
1 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; |
再在容器中执行该sql脚本:
1 | docker exec -i waline-mysql mysql -u root -p<root密码> db_waline < waline.sql |
使用DataGrip测试mysql能否连接,同时查看表是否成功创建(也可以其他方法测试):

部署Waline服务
然后使用docker快速部署waline服务:
1 | docker run -d --name waline-server \ |
输入docker ps -a
查看容器是否运行正常。
此时访问 <你的服务器公网ip>:8360
测试是否能访问waline服务,并输入评论测试。

此时可能会出现以下的报错:

这是由于 MySQL 8.0 引入了一个新的身份验证插件 caching_sha2_password
,而较旧的 MySQL 客户端(包括某些 Node.js MySQL 客户端)默认不支持这种认证方式。
解决:进入 MySQL 容器并修改 waline_user
用户的认证方式:
1 | docker exec -it waline-mysql mysql -u root -p |
然后在 MySQL 控制台中执行以下 SQL 命令来更改认证方式:
1 | ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '<root密码>'; |
再次尝试,成功!

配置Hexo next
首先,在blog/目录下安装waline:
1 | npm install @waline/hexo-next --save |
然后打开next主题配置文件_config.next.yml,找个地方输入以下内容并保存:
1 | # Waline 评论 |
然后使用命令三件套测试,到网页进行评论:

配置SSL证书
但此时,如果你hexo d部署后,如果尝试进行评论会报错“Failed to fetch”,查看docker logs waline-server
会发现报错:
1 | Mixed Content: The page at 'https:/xxxxxxx' was loaded over HTTPS, but requested an insecure resource |
这是典型的 混合内容问题(Mixed Content)。具体来说,问题出现在你的网站是通过 HTTPS 加载的,但是你请求的 Waline 服务是通过 HTTP 协议进行访问的。由于现代浏览器的安全策略,浏览器会阻止从 HTTPS 页面加载 HTTP 资源,从而导致评论功能无法正常工作。
因此我们需要为Waline 后端设置 SSL 证书,使其能够通过 HTTPS 协议提供服务。
设置子域名
由于 Let’s Encrypt 只会为域名发放证书,而不会给IP地址发放,因此我们需要为waline服务(也就是服务器)绑定一个域名。但是我们的域名已经绑定到我们的网站了,怎么办呢?
可以将服务器绑定到一个子域名,比如我们的域名是 jinqiqing.cn,那么我们将服务器IP绑定到 ecs.jinqiqing.cn 和 waline.jinqiqing.cn 两个子域名(这两个子域名都指向同一个ip,只是为了名字好看)。在域名控制台,进入 域名解析,按如下添加记录。
此外,以后还可以使用ssh root@ecs.jinqiqing.cn
的方式连接服务器了,不用再记难记的ip地址。

为域名配置SSL证书
使用免费的 Let’s Encrypt SSL 证书,配合 Certbot 工具来自动化安装和配置证书,在服务器执行命令:
1 | apt install certbot |
然后按照提示操作。结果我遇到了403 Forbidden报错:
结果发现:
看来还是需要进行域名备案啊。
备案成功后,再次尝试:
成功,同时可以发现,证书有效期是90天。
然后用nginx配置证书:
1 | apt install nginx python3-certbot-nginx |
然后会跳出交互,问为哪个域名配置,输入域名。然后会问是不是用已有的证书配置,输入 1(是)。
但此时,我们只是能通过https访问ecs.jinqiqing.cn
,还不能访问https://ecs.jinqiqing.cn:8360
;但是我们不能用nginx配置监听8360端口,因为waline服务占用了该端口。一个取巧的办法是,我们让网站访问https://ecs.jinqiqing.cn:8359
端口,然后让nginx监听ssl的8359端口,同时转发到8360,这样就完成了目标。
1 | vim /etc/nginx/sites-enable/default |
编辑该文件,在最后加入:
1 | server { |
保存后重启nginx服务:
1 | systemctl restart nginx |
别忘了在服务器的安全组中加上8359端口。
把hexo-next中的配置修改为:
1 | serverURL: https://服务器域名:8359 |
然后进行测试。
成功!