Artalk 配置参数详解(v2.10.0)

Artalk v2.10.0 配置参数详解:以二进制部署视角逐节拆解 artalk.yml 全部配置段(服务器基础、app_key、可信域名、数据库切换、管理员、审核、验证码、邮件 SMTP、Webhook 推送、缓存、日志、多站点),每项关键参数均附真实服务器实测过程与逐字回显,含环境变量覆盖优先级验证与生产配置模板。

Artalk2026/10/19

二、前置条件

目标: 把 artalk.yml 的每一节配置讲清楚:默认值是什么、改了会发生什么、怎么验证改对了。本文全部结论来自 v2.10.0 在真实服务器上的逐项实测(关键改动均重启服务并用接口回显验证),组件定位见Artalk v2.10.0 介绍与选型指南,服务化部署见Artalk Docker Compose 部署实战(v2.10.0),本文涉及的 API 调用细节见Artalk REST API 使用详解(v2.10.0)。

‍‍​​‌​# 一、环境信息

项目内容
组件版本Artalk v2.10.0(commit 1bf2140,实测 artalk version 回显 Artalk (v2.10.0/1bf2140))
部署形态单二进制安装于 /opt/artalk/artalk,systemd 服务 artalk.service 托管
配置文件/opt/artalk/artalk.yml(默认读取工作目录下的 artalk.yml,-c 参数可指定其他路径)
数据目录/opt/artalk/data(默认 SQLite 文件 ./data/artalk.db 相对于工作目录)
服务端口默认 23366,监听地址默认 0.0.0.0
实测服务器内网 192.168.146.128(测试用例中 PostgreSQL 服务监听 15432 端口)
示例账号管理员 admin / 邮箱 admin@example.com / 口令 q1w2e3r4
实测日期2026-10-19
  1. 二进制已就位且可执行:/opt/artalk/artalk version 正常输出版本信息;
  2. systemd 服务单元 /etc/systemd/system/artalk.service(官方文档推荐形态):
[Unit]
Description=Artalk Comment System
After=network.target

[Service]
Type=simple
User=artalk
WorkingDirectory=/opt/artalk
ExecStart=/opt/artalk/artalk server
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
  1. 服务管理命令:systemctl daemon-reload && systemctl enable --now artalk;日常修改配置后的生效动作统一为 systemctl restart artalk;
  2. 验证服务在跑:curl -s http://127.0.0.1:23366/api/v2/version 应返回版本 JSON;
  3. 术语约定:本文「重启验证」均指上述 systemctl 流程;「接口回显」指用 curl 直接调用本机接口(见Artalk REST API 使用详解(v2.10.0))。

三、参数查看与修改方式

1. 命令行查看当前生效值

artalk config 将最终生效配置(含环境变量覆盖后的结果)以 JSON 全量输出,节选实测(本环境):

$ artalk config
{
    "app_key": "atk-prod-key-2026-0918",
    "debug": false,
    "locale": "zh-CN",
    "timezone": "Asia/Shanghai",
    "host": "0.0.0.0",
    "port": 23366,
    "db": {
        "type": "sqlite",
        "dsn": "",
        "file": "./data/artalk.db",
        "name": "artalk",
        "host": "localhost",
        "port": 3306,
        "user": "root",
        "password": "",
        ...
    },
    "cache": {
        "enabled": false,
        "type": "builtin",
        "expires": 30,
        ...
    },
    "trusted_domains": [
        "http://192.168.146.128:8119"
    ]
}

(省略号为其余段落;该命令适合快速核对「改没改对」。)

2. 修改流程

$ vi /opt/artalk/artalk.yml     # 修改目标段
$ systemctl restart artalk       # 重启生效
$ curl -s http://127.0.0.1:23366/api/v2/version   # 确认服务恢复

3. 环境变量的覆盖优先级(实测)

ATK_* 环境变量按配置树路径映射(如 ATK_LOCALE → locale),优先级高于 artalk.yml。实测证据:将配置文件 locale: zh-CN 改为 locale: en 并重启后,接口返回的前端配置仍是中文——

$ curl -s http://127.0.0.1:23366/api/v2/conf | python3 -c "import json,sys; print(json.load(sys.stdin)['frontend_conf']['locale'])"
zh-CN

原因是服务单元环境中存在 ATK_LOCALE=zh-CN,压过了文件值。排障口诀:改了不生效,先 artalk config 看生效值,再查环境变量。部署篇中用到的 ATK_SITE_DEFAULT、ATK_SITE_URL(对应 site_default、site_url)同理。

四、参数总览

artalk.yml 顶层结构(默认模板注释齐全,逐段含义):

段作用
app_key实例级密钥:JWT 令牌签名、通知链接 key 等派生用途,首次启动自动随机生成
debug调试模式(输出更详细日志)
locale / timezone语言与时区
host / portHTTP 监听地址与端口
db数据库驱动(sqlite/mysql/pgsql/mssql)与连接参数
http请求体大小限制 body_limit、反代头 proxy_header
log日志开关与文件路径
cache缓存开关、类型(builtin/redis/memcache)、有效期
trusted_domains可信域名(跨域控制)
ssl内置证书支持(enabled/cert_path/key_path)
admin_users配置文件声明的管理员账户
moderator评论审核(关键词库、Akismet、腾讯云/阿里云内容安全、待审策略)
captcha验证码(image/turnstile/recaptcha/hcaptcha/geetest)
ip_regionIP 属地展示(含离线库路径)
img_upload图片上传(启用/路径/大小限制/公共前缀)
email邮件通知(smtp/阿里云邮件推送/sendmail)
admin_notify管理员多渠道推送(邮件/Telegram/Bark/飞书/Webhook/钉钉/Slack/LINE)
auth社交登录 OAuth2(action 地址、回调、各家凭据)
frontend前端行为透传配置(语言、暗色模式、分页、表情等)

五、核心参数分类详解(逐项实测)

1. 服务器基础:host / port

默认 host: 0.0.0.0、port: 23366。实测把端口改为 23367 并重启:

$ curl -s http://127.0.0.1:23367/api/v2/version
{"app":"artalk","version":"2.10.0","commit_hash":"1bf2140"}   # 新端口立即生效
$ curl -s -o /dev/null --max-time 3 -w '[HTTP %{http_code}]\n' http://127.0.0.1:23366/api/v2/version
[HTTP 000]    # 旧端口连接失败(预期)

改回 23366 重启后新端口恢复回显。host 建议生产保持 0.0.0.0 并由防火墙/反代控制 exposure;debug: true 仅排障时开启(日志含 SQL 细节)。

2. app_key:实例密钥(改动会导致全员掉线)

首次启动自动生成随机值(形如 app_key: "#oR!CoF&1KFyY&bo")。它用于签名登录 JWT:修改 app_key 等于吊销全部已发令牌。实测:将 app_key 改为 atk-prod-key-2026-0918 并重启后,此前获取的 token 立即失效——

$ curl -s http://127.0.0.1:23366/api/v2/user -H "Authorization: Bearer <旧token>"
{"user":null,"is_login":false,"notifies":[],"notifies_count":0}
[HTTP 200]

用管理员账号重新登录(POST /api/v2/auth/email/login)拿到的令牌恢复正常(is_login: true)。生产要点:该值等同密码,不要外泄;确需轮换时安排用户重新登录。

3. trusted_domains:可信域名(CORS 控制层)

默认空数组(放行任意 Origin)。实测配置为 trusted_domains: ["http://192.168.146.128:8119"] 后:

  • 请求头 GET /api/v2/conf/domain 会返回当前 Origin 的信任判定:
$ curl -s http://127.0.0.1:23366/api/v2/conf/domain -H 'Origin: http://192.168.146.128:8119'
{"origin":"http://192.168.146.128:8119","is_trusted":true}
[HTTP 200]
  • 关键实测结论:trusted_domains 是 CORS 响应头控制而非服务端拒绝——用 curl 携带未信任 Origin 提交评论,评论照样创建成功(返回 id),但响应头不会携带 Access-Control-Allow-Origin,浏览器会拦截该跨域响应。两种 Origin 的响应头实测对比:
未信任 Origin(curl 提交成功,但无 ACAO 头,浏览器场景被拦):
HTTP/1.1 200 OK
已信任 Origin:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://192.168.146.128:8119

因此:接口层脚本调用不受此限制;浏览器端集成页必须保证「站点 URL 域名 = 访问 Origin」或把 Origin 加入 trusted_domains。

4. db:数据库驱动(SQLite → PostgreSQL 切换实测)

默认 SQLite(零依赖):type: sqlite、file: ./data/artalk.db(相对工作目录,即 /opt/artalk/data/artalk.db)。切换其他驱动只需改 db 段,表结构在启动时自动迁移。MySQL/PostgreSQL 段模板:

db:
  type: pgsql          # sqlite / mysql / pgsql / mssql
  dsn: ""              # 优先使用 DSN;为空则用下面分项
  file: ./data/artalk.db
  name: artalk
  host: 192.168.146.128
  port: 15432
  user: artalk
  password: "q1w2e3r4"
  table_prefix: ""
  charset: utf8mb4
  ssl: false

切换实测(PostgreSQL 16,库与用户 artalk 预先创建):改 type: pgsql 并指向 15432 端口测试库,重启后服务正常启动,数据库内自动建出 8 张表:

$ psql -U artalk -d artalk -c '\dt'
             List of relations
 Schema |         Name         | Type  |  Owner
--------+----------------------+-------+---------
 public | artrans              | table | artalk
 public | cache                | table | artalk
 public | comments             | table | artalk
 public | notify               | table | artalk
 public | pages                | table | artalk
 public | sites                | table | artalk
 public | users                | table | artalk
 public | votes                | table | artalk
(8 rows)

随即提交一条评论验证写入链路,并回查数据库:

$ psql -U artalk -d artalk -c "SELECT c.id, u.name, c.content FROM comments c JOIN users u ON u.id=c.user_id ORDER BY c.id DESC LIMIT 1;"
 id |   name   |         content
----+----------+-------------------------
  1 | PG验证员 | PostgreSQL 驱动验证评论
(1 row)

注意:切换驱动不会迁移既有数据,SQLite 存量数据需用 artalk export(Artrans)导出后再 artalk import 导入新库。

5. 管理员账户:admin_users 与 CLI

配置文件方式(默认注释示例,password 支持 bcrypt/md5):

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

CLI 方式(推荐,立即生效):

$ artalk admin --name admin --email admin@example.com --password q1w2e3r4
创建管理员账户
Name:  admin
Mail:  admin@example.com

重复执行同参数命令会重置口令:

账户已存在, 密码已修改

忘记管理员口令时用第二条直接重置即可。

6. moderator:审核策略

关键字段:pending_default(新评论默认待审)、api_fail_block(检测服务异常时是否拦截)、akismet_key、tencent.*(腾讯云文本内容安全)、aliyun.*(阿里云内容安全)、keywords(本地关键词过滤,支持 files 引词库与异常处理策略)。

待审实测:pending_default: true 重启后提交评论,接口回显该评论进入待审(is_pending = True);管理员登录后用 PUT /api/v2/comments/8 将 is_pending: false 即审核放行,回显 id = 8 | is_pending = False | visible = True。注意 PUT 需要携带全部编辑字段,缺一个都会报 400(如 {"msg":"Is_collapsed必须填写"}),完整字段清单见Artalk REST API 使用详解(v2.10.0)。

7. captcha:验证码(默认开启,务必知晓)

默认模板即为开启状态:enabled: true、always: false、captcha_type: image、action_limit: 3、action_reset: 60。语义:同一客户端连续 3 次写操作(action_reset 秒内)后强制验证码;always: true 则每次都验证。

实测:在默认配置下连续提交评论,第 4 次起返回 403 并附带 base64 图片数据(节选):

{"img_data":"data:image/png;base64,iVBORw0KGgoAAAANSU...","msg":"需要验证码"}
[HTTP 403]

查询当前是否需要验证码:

$ curl -s "http://127.0.0.1:23366/api/v2/captcha/status?page_key=/post/hello.html&site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2"
{"is_pass":true}
[HTTP 200]

对接第三方验证码(Turnstile/reCAPTCHA/hCaptcha/Geetest)在对应子段填 site_key/secret_key 并改 captcha_type。API 调试与爬虫场景可临时 enabled: false。

8. email:邮件通知(SMTP 实测收信)

默认 enabled: false,send_type: smtp。SMTP 关键字段:

email:
  enabled: true
  send_type: smtp          # smtp / ali_dm / sendmail
  send_name: "{{reply_nick}}"
  send_addr: noreply@quzuo.net
  mail_subject: "[{{site_name}}] {{page_title}} 的新评论"
  mail_tpl: default        # 内置模板或自定义模板文件
  smtp:
    host: 192.168.146.128
    port: 8125
    username: noreply@quzuo.net
    password: ""
    ssl: false

实测:本机 8125 端口运行 SMTP 调试服务,配置指向后重启,调用管理员接口 POST /api/v2/send_email({"subject":"[Artalk 测试] SMTP 配置验证邮件","body":"这是 Artalk 通过 SMTP 发出的测试邮件正文。","to_addr":"admin@example.com"},回显 {"msg":"Success"} [HTTP 200])。调试服务收到的完整邮件头与正文(逐字实录,UTF-8 编码头为 Artalk 自动构造):

---------- MESSAGE FOLLOWS ----------
mail options: ['BODY=8BITMIME']
b'Mime-Version: 1.0'
b'Date: Mon, 19 Oct 2026 15:28:00 +0800'
b'To: admin@example.com'
b'Subject: =?UTF-8?q?[Artalk_=E6=B5=8B=E8=AF=95]_SMTP_=E9=85=8D=E7=BD=AE=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E9=82=AE=E4=BB=B6?='
b'Message-ID: <FwP6FjiETwpJ6Y4l0kM6ipaHjFgms6yZ@quzuo.net>'
b'From: =?UTF-8?q?Artalk_=E7=9A=84=E5=8D=9A=E5=AE=A2?= <noreply@quzuo.net>'
b'Content-Type: text/html; charset=UTF-8'
b'Content-Transfer-Encoding: quoted-printable'
b'X-Peer: 10.89.44.2'
b''
b'=E8=BF=99=E6=98=AF Artalk =E9=80=9A=E8=BF=87 SMTP =E5=8F=91=E5=87=BA=E7=9A='
b'=84=E6=B5=8B=E8=AF=95=E9=82=AE=E4=BB=B6=E6=AD=A3=E6=96=87=E3=80=82'
------------ END MESSAGE ------------

(From 名取自 site_default「Artalk 的博客」,From 地址即 send_addr。)真实邮件下发建议配额充足的 SMTP 服务(如企业邮箱或阿里云邮件推送 ali_dm),排障时先看 debug: true 日志中的 [Email] 行。

9. admin_notify:多渠道推送(Webhook 实测)

管理员通知默认含邮件通道(email.enabled: true,每条新评论推送给管理员)。Webhook 关键字段:

admin_notify:
  notify_tpl: default
  email:
    enabled: true
    subject: "站长通知:有新评论"
    tpl: ""
  telegram:   { enabled: false, api_token: "", chat_id: "" }
  bark:       { enabled: false, server_url: "" }
  lark:       { enabled: false, webhook_url: "" }
  webhook:
    enabled: true
    url: "http://192.168.146.128:8126/hook"
  ding_talk:  { enabled: false, token: "", secret: "" }
  slack:      { enabled: false, webhook_url: "" }
  line:       { enabled: false, channel_access_token: "", user_ids: [] }

实测:新提交一条评论后,Webhook 接收端收到的请求(逐字实录,User-Agent: Go-http-client/1.1,JSON 单包 1200 字节):

{"notify_subject":"","notify_body":"@通知测试员:\n\n这条评论将触发邮件与 Webhook 通知\n\nhttp://192.168.146.128:8119/post/hello.html?atk_comment=9&atk_notify_key=NXUGN","comment":{"id":9,"content":"这条评论将触发邮件与 Webhook 通知","content_marked":"\u003cp\u003e这条评论将触发邮件与 Webhook 通知\u003c/p\u003e\n","user_id":11,"nick":"通知测试员","email_encrypted":"e1d36904c3aea3a1218b172153c47bfc9e119ccd5d61ff6a8c50ec02fe8dc6bd","link":"","ua":"curl/7.81.0","date":"2026-10-19 15:22:17","is_collapsed":false,"is_pending":false,"is_pinned":false,"is_allow_reply":true,"is_verified":false,"rid":0,"badge_name":"","badge_color":"","visible":true,"vote_up":0,"vote_down":0,"page_key":"/post/hello.html","page_url":"http://192.168.146.128:8119/post/hello.html","site_name":"Artalk 的博客"},"parent_comment":{"id":0,"content":"","content_marked":"","user_id":0,"nick":"","email_encrypted":"","link":"","ua":"","date":"","is_collapsed":false,"is_pending":false,"is_pinned":false,"is_allow_reply":false,"is_verified":false,"rid":0,"badge_name":"","badge_color":"","visible":false,"vote_up":0,"vote_down":0,"page_key":"","page_url":"","site_name":""}}

字段结构固定三段:notify_subject / notify_body(通知文案,含评论落地页链接与 notify_key)+ comment(评论对象)+ parent_comment(父评论,无回复时为空对象)。利用该结构可对接任意自建自动化(如同步到群机器人、工单系统)。飞书(Lark)、钉钉、Telegram、Bark、Slack、LINE 通道均为「enabled + 凭据」两三行的同构配置。

10. cache:缓存

默认 enabled: false、type: builtin、expires: 30(分钟)。实测关闭状态下调用缓存管理接口直接被拒:

$ curl -s -X POST http://127.0.0.1:23366/api/v2/cache/warm_up -H "Authorization: Bearer <token>"
{"msg":"cache disabled"}
[HTTP 400]

改为 enabled: true 重启后:

$ curl -s -X POST http://127.0.0.1:23366/api/v2/cache/warm_up -H "Authorization: Bearer <token>"
{"msg":"任务已开始在后台执行,请稍后..."}
[HTTP 200]
$ curl -s -X POST http://127.0.0.1:23366/api/v2/cache/flush -H "Authorization: Bearer <token>"
{"msg":"任务已开始在后台执行,请稍后..."}
[HTTP 200]

type 可切 redis(server 字段填地址)与 memcache;多实例共享缓存或高并发场景建议 Redis。

11. log:日志

默认 enabled: true、filename: ./data/artalk.log(即 /opt/artalk/data/artalk.log,实测文件正常生成与滚动追加)。日志同时输出到 stdout(journalctl -u artalk 可见)。ERROR 级别记录无效参数、HTTP 4xx 等事件,含请求 ID(uuid)、路径、来源 IP、User-Agent,排障价值高。注意 debug: true 时日志量显著增大。

12. 多站点:site_default / site_url 与站点管理

Artalk 的多站点是实例级集中管理:一个进程服务多个站点,评论、页面、用户按站点隔离。相关参数与机制:

  • site_default:默认站点名(首次启动创建);site_url:默认站点地址。实测部署时用环境变量 ATK_SITE_DEFAULT=Artalk 的博客、ATK_SITE_URL=http://192.168.146.128:8119 设置后,站点列表中默认站点即携带该 URL(见Artalk REST API 使用详解(v2.10.0)GET /api/v2/sites 回显);
  • app_key 在多站点体系中的角色:它是实例级密钥,为 JWT 令牌与通知链接的 atk_notify_key 提供签名来源——跨站点共享同一实例时,管理员令牌对所有站点有效,站点间隔离由「站点成员」体系控制(管理面板中分配各站点管理员);
  • 站点的增删改查走 GET/POST/PUT/DELETE /api/v2/sites* 接口(实测回显见Artalk REST API 使用详解(v2.10.0)),前端集成时通过 site: '站点名' 指定归属;
  • 跨域:每个站点的前端 Origin 都应加入 trusted_domains(见本文第 3 节),否则浏览器端无法读取响应。

13. 其余段落速览

  • http.body_limit: 100(MB):上传体积上限,配合图片上传调大;http.proxy_header:置于反代后填写真实 IP 传递头(如 X-Real-IP);
  • ssl:Artalk 自带证书挂载能力(cert_path/key_path),通常建议由反代终结 TLS 而非内置;
  • ip_region:IP 属地展示开关与离线数据路径,默认关闭;
  • img_upload:默认开启本地上传(路径、大小、允许后缀、公共前缀 up_public_path);
  • auth:社交登录开关与 OAuth2 凭据(GitHub/Google 等 13 家),auth.enabled: false 时仅匿名+邮箱;
  • frontend:前端透传(locale、darkMode、pagination、emoticons、gravatar 等),键名与前端配置一致,改后重启即可在前端生效。

六、生产配置模板(组合示例)

以下为经实测各单项后的常用生产组合(可直接替换 <> 内容):

app_key: "<首次启动已随机生成,保留或自定义强随机值>"
debug: false
locale: zh-CN
timezone: Asia/Shanghai
host: 0.0.0.0
port: 23366

db:
  type: pgsql
  name: artalk
  host: 127.0.0.1
  port: 5432
  user: artalk
  password: "<DB口令>"
  charset: utf8mb4

http:
  body_limit: 100
  proxy_header: "X-Real-IP"    # 置于反代后

log:
  enabled: true
  filename: ./data/artalk.log

cache:
  enabled: true
  type: builtin
  expires: 30

trusted_domains:
  - "https://blog.example.com"
  - "https://docs.example.com"

admin_users: []                 # 建议用 CLI: artalk admin

moderator:
  pending_default: false        # 高流量站点可改 true 全量先审后放
  keywords:
    enabled: true
    files:
      - ./data/keywords.txt

captcha:
  enabled: true
  always: false
  captcha_type: image
  action_limit: 3
  action_reset: 60

email:
  enabled: true
  send_type: smtp
  send_name: "{{reply_nick}}"
  send_addr: "noreply@example.com"
  smtp:
    host: "smtp.example.com"
    port: 465
    username: "noreply@example.com"
    password: "<SMTP口令>"
    ssl: true

admin_notify:
  email:
    enabled: true
    subject: "站长通知:有新评论"
  webhook:
    enabled: true
    url: "https://automate.example.com/hook/artalk"

frontend:
  locale: zh-CN

七、常见问题

  1. 改了配置不生效:先 artalk config 看生效值,再确认 systemctl restart artalk 已执行;仍不符则排查 ATK_* 环境变量覆盖(实测案例见本文第三节第 3 小节)。
  2. 评论接口报 {"msg":"Page_key必须填写"} / {"msg":"Site_name必须填写"}:参数缺失的标准报错(400),按提示补齐字段即可,不是服务异常。
  3. app_key 改完后大家都被登出:JWT 由 app_key 签名,换 key 即全员令牌失效(实测 is_login:false),属预期行为,重新登录即可。
  4. curl 提交评论莫名 403「需要验证码」:默认 action_limit=3 的频率策略(本文第 5 节第 7 小节实测),API 调试时可临时关闭验证码或等待 60 秒计数重置。
  5. trusted_domains 配了还是能 curl 提交:它控制 CORS 响应头,不拦截非浏览器请求(本文第 3 节实测);要拦截接口层滥用应使用审核/验证码/关键词。
  6. 切换数据库后旧评论不见了:驱动切换不迁数据,用 artalk export 导出 Artrans 再 artalk import 到新库。
  7. 邮件发不出:确认 email.enabled: true 与 SMTP 凭据;开启 debug: true 后重启,日志过滤 [Email] 关键字查看发送与失败详情;用 POST /api/v2/send_email 快速自测链路。
  8. Webhook 没触发:确认 admin_notify.webhook.enabled: true 且 URL 可从服务器出网访问;Webhook 仅在产生通知的事件(新评论/回复)时 POST,参考本文第 9 节的实测报文排查接收端。

参考链接

  1. Artalk GitHub 仓库:https://github.com/ArtalkJS/Artalk
  2. 配置参考文档:https://artalk.js.org/zh/guide/backend/config.html
  3. 邮件通知文档:https://artalk.js.org/zh/guide/backend/email.html
  4. 管理员与多站点:https://artalk.js.org/zh/guide/backend/multi-site.html
  5. v2.10.0 Release:https://github.com/ArtalkJS/Artalk/releases/tag/v2.10.0