Halo Twikoo 插件以及 ssl 部署

背景 & 目标

前段时间将站点从 wordpress 迁移到了 halo 上,而 halo 默认的评论组件很不好用,需要在你的站点注册一个账号后,才可以使用,正好我当前使用的 hao 主题刚好内置了 twikoo 评论插件的支持

而且之前一直懒得对站点增加 https 的支持,正好凑着这个机会,一起升级一下。本文的方案希望在一台机器上完成所有功能,不去借助类似 vercel 等服务的部署,所有组件均运行在 docker 中,方便后续迁移和升级

服务器环境

目前我的站点部署在 阿里云 的 ECS 上,这几天我也试着折腾了一下 CloudFlare 使用 tunnel 代理到家用宽带上,奈何速度非常感人,即使用 DDNS 速度也非常不理想

建议如果追求站点在国内的打开速度,最好还是老老实实交保护费

文件层级

这里推荐把所有相关的内容放在一起,通过文件夹区分每个服务存放的内容,这里的三个文件夹就是我们需要配置的 3 个服务,其中 halo2 的配置已经在 Halo 建站 这篇文章中讲过,本篇不再赘述

.
├── halo2
├── nginx
└── twikoo

Twikoo 配置

官方文档 中提供了如下 docker compose 配置

version: '3'
services:
  twikoo:
    image: imaegoo/twikoo
    container_name: twikoo
    restart: unless-stopped
    ports:
      - 8080:8080
    environment:
      TWIKOO_THROTTLE: 1000
    volumes:
      - ./data:/app/data

安装过程非常简单,按照如下命令运行即可,注意 volumes 后面的内容 ./data,我希望 docker-compose.yaml 文件和数据放在同一个文件夹下面, 方便转移和备份

mkdir twikoo
cd twikoo
vi docker-compose.yaml
# 自行填入内容
docker compose up -d
# 或者 docker-compose up -d 取决你的环境

到这里我们安装就已经好了,但是先不着急配置,此处也需要对 twikoo 的内容进行 ssl 加密处理

Nginx Proxy Manager

同样我们可以在 官方文档 中找到 dcoker compose 的配置内容

version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

安装也很简单,按照如下指令运行即可

mkdir nginx
cd nginx
vi docker-compose.yaml
# 自行复制
docker compose up -d

此时我们开启了三个端口,其中 80/443 是给 web 服务器使用的,而 81 端口则是 NPM 的管理界面,通常这个端口 ECS 是不开放的,需要你在运营商的后台配置一下 安全策略组,开放 81 端口,这里以 阿里云为例

我这已经配好了,后面很长时间不需要这个功能,所以调整为了拒绝

接着使用 服务器 ip:81 访问,NPM 默认的账号密码如下,记得登录后修改

Email:    admin@example.com
Password: changeme

申请证书

在 SSL Certificates 下新增证书,这里你可以填写 *.example.com,只申请一个,适配所有服务的证书,我这里选择挨个配置

这里我申请了三个域名的 ssl 证书,注意这里的 twikoo.liuocean.com,此处我希望 twikoo 直接使用二级域名进行访问,这样 8080 端口也可以保持关闭了

twikoo 二级域名 DNS 解析

这里创建一个 A 类型的解析,主机记录填入 twikoo,记录值填写为当前服务器的公网 IP

具体以实际运营商的后台为准,下图为阿里的配置界面

连接 docker 网络

目前我们已经创建了 halotwikoo 以及 NPM 三个容器,但是这三个容器处于不同网段中,容器和容器之间互相不清楚如何建立连接,此时我们需要使用 docker network connet 网络 容器名 的方式进行联通

为了拿到 网络容器名 我们需要用到如下两个指令

docker ps
# 最后一列 NAMES 既是容器名
CONTAINER ID   IMAGE                           ... NAMES
96772b04b474   jc21/nginx-proxy-manager:latest ... nginx-app-1
28cc2ee3cbf7   halohub/halo:2.8                ... halo
a0c44aaf8a4e   imaegoo/twikoo                  ... twikoo
8da3981f70ed   postgres:latest                 ... halodb
docker network ls
# 第二列 NAME 则是网络名
NETWORK ID     NAME                 DRIVER    SCOPE
c1646cd554fc   bridge               bridge    local
ac59c5c5cab8   halo2_halo_network   bridge    local
f266311bb0a9   host                 host      local
ebd8b3fce3d3   nginx_default        bridge    local
5eec799dd6a0   none                 null      local
4657be95c638   twikoo_default       bridge    local
673c83231bb2   www_default          bridge    local

后面我们需要配置 NPM 的反代规则,因此需要将 nginx-app-1 同时连接到 halo2_halo_networktwikoo_default 中,此时则需要运行 connet 指令

docker network connect halo2_halo_network nginx-app-1
docker network connect twikoo_default nginx-app-1

具体请以命令中实际显示的值为准,这里只作为示例展示

查看容器的具体 IP

到了这里我们已经做好了 docker bridge 内网跳发规则配好了,但是由于 NPM 运行在 docker 中,反代转发时,需要填写容器内部的 IP,也就是 halotwikoo 容器所分配的具体 IP,此时需要使用 inspect 指令,查询容器的 ip

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' halo
172.18.0.3

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' twikoo
172.24.0.2

记住你电脑上的这两个值,等会要用

反代规则配置

我们需要创建如下三个 proxy host 配置,图中第一个和第三个配置一样

我这里 www 和一级域名实际上使用的是两个 ssl 加密证书

以一级域名的配置为例,首先填写 以及域名 liuocean.com,协议为 http,forward hostname/ip 中填写的是 halo 在 docker 容器中分配的 IP地址,而最后的 8090 则是容器内部的端口号

最后在 SSL 选项卡中,选择使用的 ssl 证书,并打开强制 SSL 即可

twikoo 也是同样道理,自行配置

主题后台配置

我们来到 console 后台,在主题选项卡中向左滑,点击评论按钮,即可出现具体配置,在 后端 URL 中,我们填入刚刚配好的 twikoo 二级域名

注意,一定要增加 https:// 否则 twikoo 会当做环境 id 处理,发送到腾讯云函数上

twikoo 后台配置

随便来到你博客的一篇文章,拉到最下面的评论区,点击齿轮即可弹出配置选单,第一次配置时会提示你输入管理密码,更详细的配置直接阅读面板的说明就好了,非常简单~ 我这里就不再一一赘述了

最后

halo 建站到此基本上结束了,整体体验很不错,全都容器化管理后,如果今后需要整站迁移也非常舒服,但是 halo 整体的生态目前还处于前期的发展阶段,有一些功能缺失导致我发文流程被中断(mweb 上传)

同时一些非官方群中的交流氛围也有待商榷,充斥着傲慢和不专业,奈何我对 web 开发不熟,不然一些小功能的缺失我就自己写了,哈哈