Artalk自托管评论系统搭建与配置

Artalk 是一款简单易用但功能丰富的评论系统,可以做到开箱即用,能轻松的置入任何博客、网站、Web 应用。

Artalk官网

环境准备


部署过程


一、系统初始化,更新索引

#更新索引库
sudo apt-get update

二、创建Artalk容器

#切换到root用户
sudo -i

#在root目录下递归的创建一些文件夹,如果父目录不存在则先创建出来
mkdir -p /root/data/docker_workspace/artalk

#进入到artalk目录下
cd /root/data/docker_workspace/artalk

#创建一个docker-compose.yml配置文件
touch docker-compose.yml

#编辑该文件
vim docker-compose.yml

将下面代码复制到docker-compose.yml中保存即可(指定的端口事先要在服务器内部和云服务商后台开放)

version: '3.5'
services:
  artalk:
    container_name: artalk
    image: artalk/artalk-go
    restart: always
    ports:
      - 8080:23366  # 将容器的 23366 端口(TCP)映射到宿主机的 8080 端口,8080端口可自行更改
    volumes:
      - ./data:/data
#拉取项目镜像并在后台启动容器
docker-compose up -d

登录Artalk后台配置界面

打开浏览器,地址栏内输入服务器IP:8080端口形式访问。默认情况下是没有用户可供登录的,这时需要用命令的方式创建个管理员账号:

# 该命令请确保在artalk目录下执行
docker exec -it artalk artalk admin

博客引入组件

以Ghost casper默认主题为例,在post.hbs模版的</article>前的{{#if comments}}前面插入Artalk的初始化脚本

<div id="Comments"></div> <!-- 创建一个用于显示评论的div元素,id为Comments -->
<script>
Artalk.init({
  	el:        '#Comments',  // 指定评论系统的容器元素,使用CSS选择器'#Comments'
  	pageKey:   '{{article.url}}',  // casper主题的文章链接选择器
  	pageTitle: '{{article.title}}',  // casper主题的标题选择器
  	server:    'https://example.com',  // 自己搭建的Artalk评论服务器域名地址
  	site:      '网站名称',  // 网站名称
  	avatarURLBuilder: (c) => {  // 自定义头像URL生成器函数
		if (c.is_admin) {
			return "管理员头像 URL";  // 如果是管理员,使用指定的管理员头像URL
		}
		return `https://cravatar.cn/avatar/${c.email_encrypted}`;  // 否则,使用加密的邮箱生成Gravatar头像URL
	}
})
</script>

最后如图所示

你会发现两个问题:1、avatarURLBuilder: (c) 函数功能官方文档中并没有,这是因为如果不加这个函数功能,用户默认留言的头像是不显示的。这个函数是随机给到用户的初始头像;2、官方的pageKey和pageTitle两个参数建议的值可以为空,但是在我的主题里面是自动识别不出来的,所以如果你发现自己的网站登录Artalk后台初始化的时候无法识别文章列表,也就是文章下面加载不出评论界面,请自行用浏览器的开发者工具针对自己的网页文章和网页标题两个元素自行选择对应的元素选择器值填写就可以了。

在自己主页的的<head></head>标签中引入Artalk的css、js代码

<!-- CSS -->
<link href="https://your_domain/dist/Artalk.css" rel="stylesheet" />
<!-- JS -->
<script src="https://your_domain/dist/Artalk.js"></script>

# 注意:https://your_domain是你的Artalk服务器域名

上述的Artalk css、js也可使用公共的CDN资源,以下是公共CDN资源例表,任选一组即可

CDN 来源 JavaScript 链接 CSS 链接
CDNJS https://cdnjs.cloudflare.com/ajax/libs/artalk/2.8.6/Artalk.js https://cdnjs.cloudflare.com/ajax/libs/artalk/2.8.6/Artalk.css
SUSTech Mirrors (境内) https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/artalk/2.8.6/Artalk.js https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/artalk/2.8.6/Artalk.css
Staticfile CDN (境内) https://cdn.staticfile.org/artalk/2.8.6/Artalk.js https://cdn.staticfile.org/artalk/2.8.6/Artalk.css
BootCDN (境内) https://cdn.bootcdn.net/ajax/libs/artalk/2.8.6/Artalk.js https://cdn.bootcdn.net/ajax/libs/artalk/2.8.6/Artalk.css
75CDN (境内) https://lib.baomitu.com/artalk/2.8.6/Artalk.js https://lib.baomitu.com/artalk/2.8.6/Artalk.css
UNPKG https://unpkg.com/artalk@2.8.6/dist/Artalk.js https://unpkg.com/artalk@2.8.6/dist/Artalk.css
JSDELIVR https://cdn.jsdelivr.net/npm/artalk@2.8.6/dist/Artalk.js https://cdn.jsdelivr.net/npm/artalk@2.8.6/dist/Artalk.css

重新登录Artalk后台控制面板,进入设置界面,将语言更改为中文,网页重新刷新。

Artalk功能配置


一、可信域名站点添加

点击最右侧的+号,将自己的博客网站域名添加进去,Artalk支持添加多域名站点的管理。

二、启用IP属地

在开启 IP 属地展示功能之前,需要下载一个数据库文件:

下载后请手动放置到 ./data/ 目录下,文件命名为:ip2region.xdb

在管理面板的IP属地中勾选"启用 IP 属地展示",确保数据文件路径的右侧地址栏里填写的是./data/ip2region.xdb,显示精度支持省、城市、国家三个选项。

三、邮件通知

勾选"启用邮件通知"(如果想让用户以邮件的方式知道自己的消息有人回复,可以开启此功能。)

名称 设置内容
发送方式 smtp
发信人昵称 {{reply_nick}}
发信人地址 example@qq.com
邮件标题 [{{site_name}}] 您收到了一个回复来自于 @{{reply_nick}}
邮件模板文件 default

SMTP发送设置

名称 设置内容
发件地址 smtp.qq.com
发件端口 587
用户名 example@qq.com
密码 注意是邮箱授权密码而非登录密码

四、用户登录方式

Artalk默认支持匿名登录,不需要邮箱验证,但是为了防止垃圾评论和敏感词汇,我自己做了邮箱验证和人工审核

1、邮箱登录

用户需要注册,获取验证码才能登录。后台进入社交登录

名称 设置内容
启用社交登录 ☑️
允许匿名评论 禁止
回调地址 暂时默认

EMAIL

名称 设置内容
启用邮箱密码登录 ☑️
邮箱验证邮件标题 您的注册码邮件
邮箱验证邮件模板 default

2、启用Github联合验证登录

该登录功能需要用户设备可以魔法上网才能使用

Github

名称 设置内容
Enabled ☑️
ClientId 见下方教程
ClientSecret 见下方教程

五、Github授权信息获取

登录github官网,右上角处点击自己的头像列表,进入Settings菜单,左侧列表底部找到Developer settings菜单,选择OAuth Apps菜单,右侧区域点击Register a new application按钮,参考下图进行填写:

填完后点击注册按钮,在Client secrets选项的地方点击Generate a new client secert按钮创建一个新的客户端密钥,这个密钥只有创建的时候才会明文显示,后续无法再查看具体信息,所以请保管好。

创建完成后,点击下方的Update application绿色按钮保存即可。此时应用创建完成。你可以看到自己的Client IDClient secrets两个参数。将这两个参数填写进Artalk后台的社交登录-GitHub中对应的位置,社交登录的回调地址栏里填写你在github中填写的`Authorization callback URL`值,点击管理后台右下角的应用保存。用户登录效果如图所示:

注意!!!

应用注册好的时候,你在github应用管理界面做任何的更新操作,github已经成功授权的将会失效!这个时候不管你是删除已有的,还是重新生成新的Client secrets也好,填写到Artalk后台对应位置中,用户以github方式登录将会失败,这时你只能进入github应用注册界面,将已有的应用给删除,然后重新创建新的才行。

六、表情包更换

界面配置的表情包一栏里填写自己的标签json文件,我这里用的是一个开源的:

https://cdn.jsdelivr.net/npm/sticker-heo@2022.7.5/artalk.json

表情链接

配置修改的方式

Artalk的配置对新手很友好,几乎90%都可以通过后台去改。除此之外修改artalk.yml文件效果也是一样的。

# 服务器地址
host: "0.0.0.0"

# 服务器端口
port: 23366

# 加密密钥
app_key: ""

# 调试模式
debug: false

# 语言 ["en", "zh-CN", "zh-TW", "jp", "fr", "ko", "ru"]
locale: zh-CN

# 时间区域
timezone: Asia/Shanghai

# 默认站点名
site_default: 默认站点

# 登录有效时长 (单位:秒)
login_timeout: 259200

# 数据库
db:
  # 数据库类型 ["sqlite", "mysql", "pgsql", "mssql"]
  type: sqlite
  # 数据库文件 (仅 SQLite 数据库需填写)
  file: ./data/artalk.db
  # 数据库名称
  name: artalk
  # 数据库地址
  host: localhost
  # 数据库端口
  port: 3306
  # 数据库账户
  user: root
  # 数据库密码
  password: ""
  # 编码格式
  charset: utf8mb4
  # 表前缀 (例如:"atk_")
  table_prefix: ""
  # 启用 SSL
  ssl: false
  # 预编译语句
  prepare_stmt: true

# 服务器
http:
  # 请求体大小限制 (单位:MB)
  body_limit: 100
  # 代理标头名 (当使用 CDN 时填写 `X-Forwarded-For` 获取用户真实 IP)
  proxy_header: ""

# 日志
log:
  # 启用日志
  enabled: true
  # 日志文件路径
  filename: ./data/artalk.log

# 缓存
cache:
  # 启用缓存
  enabled: false
  # 缓存类型 ["redis", "memcache", "builtin"]
  type: builtin
  # 缓存过期时间 (单位:分钟)
  expires: 30
  # 缓存启动预热 (程序启动时预热缓存)
  warm_up: false
  # 缓存服务器地址 (例如:"localhost:6379")
  server: ""
  # Redis 配置
  redis:
    # 连接方式 ["tcp", "unix"]
    network: tcp
    # 用户名
    username: ""
    # 密码
    password: ""
    # 数据库编号 (例如使用零号数据库填写 0)
    db: 0

# 可信域名
trusted_domains: [] # 例如:["https://artalk.example.com:23366"]

# SSL
ssl:
  # 启用 SSL
  enabled: false
  # 证书文件路径
  cert_path: ""
  # 密钥文件路径
  key_path: ""

# 管理员账户
admin_users:
  # - name: "admin"
  #   email: "admin@example.com"
  #   password: "" # 支持 bcrypt 或 md5 加密,如:"(md5)50c21190c6e4e5418c6a90d2b5031119"
  #   badge_name: "管理员"
  #   badge_color: "#0083FF"

# 评论审核
moderator:
  # 默认待审 (发表新评论需要后台人工审核后才能显示)
  pending_default: false
  # API 请求错误时拦截 (关闭此项当请求错误时让评论放行)
  api_fail_block: false
  # Akismet Key
  # (Akismet 反垃圾服务,https://akismet.com)
  akismet_key: ""
  # 腾讯云文本内容安全
  # (https://cloud.tencent.com/document/product/1124/64508)
  tencent:
    enabled: false
    secret_id: ""
    secret_key: ""
    region: ap-guangzhou
  # 阿里云内容安全
  # (https://help.aliyun.com/document_detail/28417.html)
  aliyun:
    enabled: false
    access_key_id: ""
    access_key_secret: ""
    region: cn-shanghai
  # 关键词过滤 (本地离线词库)
  keywords:
    enabled: false
    # 匹配成功设为待审状态
    pending: false
    # 词库文件 (支持多个词库文件)
    files:
      - ./data/词库_1.txt
    # 词库文件内容分割符 (例如填写 "\n" 文件中一行一个关键词)
    file_sep: "\n"
    # 替换字符
    replace_to: x

# 验证码
captcha:
  # 启用验证码
  enabled: true
  # 总是需要验证码
  always: false
  # 验证类型 ["image", "turnstile", "recaptcha", "hcaptcha", "geetest"]
  captcha_type: image
  # 激活验证码所需操作次数
  action_limit: 3
  # 重置操作计数器超时 (单位:s, 设为 -1 不重置)
  action_reset: 60
  # Turnstile
  # (https://www.cloudflare.com/products/turnstile/)
  turnstile:
    site_key: ""
    secret_key: ""
  # reCaptcha
  # (https://www.google.com/recaptcha/about/)
  recaptcha:
    site_key: ""
    secret_key: ""
  # hCaptcha (https://www.hcaptcha.com/)
  hcaptcha:
    site_key: ""
    secret_key: ""
  # Geetest 极验 (https://www.geetest.com)
  geetest:
    captcha_id: ""
    captcha_key: ""

# IP 属地
ip_region:
  # 启用 IP 属地展示
  enabled: false
  # 数据文件路径 (.xdb 格式)
  db_path: ./data/ip2region.xdb
  # 显示精度 ["province", "city", "country"]
  precision: province

# 图片上传
img_upload:
  # 启用图片上传
  enabled: true
  # 图片存放路径
  path: ./data/artalk-img/
  # 图片大小限制 (单位:MB)
  max_size: 5
  # 图片链接基础路径 (默认为 "/static/images/")
  public_path: null
  # Upgit 配置
  # (使用 Upgit 将图片上传到 GitHub 或图床:https://github.com/pluveto/upgit)
  upgit:
    # 启用 Upgit
    enabled: false
    # 命令行参数
    exec: upgit -c <upgit配置文件路径> -t /artalk-img
    # 上传后删除本地的图片
    del_local: true

# 邮件通知
email:
  # 启用邮件通知
  enabled: false
  # 发送方式 ["smtp", "ali_dm", "sendmail"]
  send_type: smtp
  # 发信人昵称
  send_name: "{{reply_nick}}"
  # 发信人地址
  send_addr: noreply@example.com
  # 邮件标题
  mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复"
  # 邮件模板文件 (填入文件路径使用自定义模板)
  mail_tpl: default
  # SMTP 发送 (启用请将发送方式设为 "smtp")
  smtp:
    # 发件地址
    host: smtp.qq.com
    # 发件端口
    port: 587
    # 用户名
    username: example@qq.com
    # 密码
    password: ""
  # 阿里云邮件推送
  # (启用请将发送方式设为 "ali_dm";参考:https://help.aliyun.com/document_detail/29444.html)
  ali_dm:
    access_key_id: ""
    access_key_secret: ""
    account_name: noreply@example.com

# 多元推送
admin_notify:
  # 通知模版 (填入文件路径使用自定义模板)
  notify_tpl: default
  # 待审评论仍然发送通知 (当评论被拦截时仍然发送通知)
  notify_pending: false
  # 嘈杂模式
  noise_mode: false
  # 邮件通知管理员
  email:
    # 开启 (当使用其他推送方式时,可以关闭管理员邮件通知)
    enabled: true
    # 邮件标题 (发送给管理员的邮件标题)
    mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复"
    # 管理员邮件模板文件 (填入文件路径使用自定义模板)
    mail_tpl: ""
  # Telegram
  telegram:
    enabled: false
    api_token: ""
    receivers:
      - 7777777
  # Bark
  bark:
    enabled: false
    server: http://day.app/xxxxxxx/
  # 飞书
  lark:
    enabled: false
    webhook_url: ""
    # 消息类型 ["text", "card"]
    msg_type: "text"
  # WebHook
  webhook:
    enabled: false
    url: ""
  # 钉钉
  ding_talk:
    enabled: false
    token: ""
    secret: ""
  # Slack
  slack:
    enabled: false
    oauth_token: ""
    receivers:
      - CHANNEL_ID
  # LINE
  line:
    enabled: false
    channel_secret: ""
    channel_access_token: ""
    receivers:
      - USER_ID_1
      - GROUP_ID_1

# 社交登录
auth:
  # 启用社交登录
  enabled: false
  # 允许匿名评论 (允许跳过验证,仅填写匿名的昵称和邮箱)
  anonymous: true
  # 回调地址 (https://example.com/api/v2/auth/{provider}/callback)
  callback: "http://localhost:23366/api/v2/auth/{provider}/callback"
  # Email
  email:
    # 启用邮箱密码登录
    enabled: true
    # 邮箱验证邮件标题
    verify_subject: "您的验证码是 - {{code}}"
    # 邮箱验证邮件模板 (填入文件路径使用自定义模板)
    verify_tpl: default
  # GitHub
  github:
    enabled: false
    client_id: ""
    client_secret: ""
  # GitLab
  gitlab:
    enabled: false
    client_id: ""
    client_secret: ""
  # Gitea
  gitea:
    enabled: false
    client_id: ""
    client_secret: ""
  # Google
  google:
    enabled: false
    client_id: ""
    client_secret: ""
  # Mastodon
  mastodon:
    enabled: false
    client_id: ""
    client_secret: ""
  # Twitter
  twitter:
    enabled: false
    client_id: ""
    client_secret: ""
  # Facebook
  facebook:
    enabled: false
    client_id: ""
    client_secret: ""
  # Discord
  discord:
    enabled: false
    client_id: ""
    client_secret: ""
  # Steam
  steam:
    enabled: false
    api_key: ""
  # Apple
  apple:
    enabled: false
    client_id: ""
    client_secret: ""
  # Microsoft
  microsoft:
    enabled: false
    client_id: ""
    client_secret: ""
  # 微信
  wechat:
    enabled: false
    client_id: ""
    client_secret: ""
  # Tiktok
  tiktok:
    enabled: false
    client_id: ""
    client_secret: ""
  # Slack
  slack:
    enabled: false
    client_id: ""
    client_secret: ""
  # Line
  line:
    enabled: false
    client_id: ""
    client_secret: ""
  # Patreon
  patreon:
    enabled: false
    client_id: ""
    client_secret: ""
  # Auth0
  auth0:
    enabled: false
    client_id: ""
    client_secret: ""
    domain: ""

# 界面配置
frontend:
  # 评论框占位文字
  placeholder: ""
  # 无评论显示文字
  noComment: ""
  # 发送按钮文字
  sendBtn: ""
  # 评论框穿梭
  editorTravel: true
  # 表情包
  emoticons: https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json
  # 投票按钮
  vote: true
  # 反对按钮
  voteDown: false
  # 用户 UA 徽标
  uaBadge: false
  # 评论排序功能
  listSort: true
  # 页面 PV 绑定元素
  pvEl: ".artalk-pv-count"
  # 评论数绑定元素
  countEl: ".artalk-comment-count"
  # 统计组件 PageKey 属性名
  statPageKeyAttr: "data-page-key"
  # 编辑器实时预览功能
  preview: true
  # 平铺模式 ["auto", true, false]
  flatMode: auto
  # 夜间模式 ["inherit", "auto"]
  darkMode: inherit
  # 最大嵌套层数
  nestMax: 2
  # 嵌套评论排序规则 ["DATE_ASC", "DATE_DESC", "VOTE_UP_DESC"]
  nestSort: DATE_ASC
  # 头像 Gravatar
  gravatar:
    # API 地址
    mirror: https://cravatar.cn/avatar/
    # API 参数
    params: d=mp&s=240
  # 评论分页
  pagination:
    # 每页评论数
    pageSize: 20
    # 加载更多模式 (关闭则使用分页条)
    readMore: true
    # 滚动加载
    autoLoad: true
  # 内容限高
  heightLimit:
    # 评论内容限高 (单位:px)
    content: 300
    # 子评论区域限高 (单位:px)
    children: 400
    # 滚动限高 (允许限高区域滚动)
    scrollable: false
  # 图片懒加载 [false, "native", "data-src"]
  imgLazyLoad: false
  # 请求超时 (单位:毫秒)
  reqTimeout: 15000
  # 版本检测
  versionCheck: true
  # 插件
  pluginURLs: []