Snikket stable.20260611.1 配置参数详解

Snikket 配置体系三层链路与全量参数参考:参数查看/修改/查证实测、核心参数逐项解析(留存、上传配额、TLS 档位、存储后端 files↔sqlite 双向迁移)、生产配置模板与常见问题。

SnikketSnikketXMPPProsody IM2026/10/30

Snikket stable.20260611.1 配置参数详解

目标:把 Snikket 的配置体系一次讲透——参数放在哪、怎么改才生效、如何查证运行时实际值,并给出全量参数参考表、核心参数逐项实测解析与一份生产可用模板。全部命令与回显来自 stable.20260611.1 实例实测(2026-10-30),部署过程见《Snikket Docker Compose 部署指南》。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(x86_64);Docker 29.9.2 + Compose v5.6.1
  • Snikket Server:snikket/snikket-server:stable,实测自报版本 Snikket release stable.20260611.1,内置引擎 Prosody trunk nightly build 2079 (2026-05-27, fa492a9d1a20)
  • 实例配置:SNIKKET_DOMAIN=snikket.local(测试域,自签证书路径),配置经 compose 的 env_file 注入四组件
  • 配置参数来源与版本依据:官方文档页 Advanced configuration(snikket.im/help/advanced/config/,查询日期 2026-10-30)+ 镜像内启动脚本与配置模板逐行核对(见第三章)

二、配置体系:参数到底放在哪

Snikket 的配置只有一个入口文件 snikket.conf(环境变量键值对),但它经三层流转才落到运行时。动手改参数前必须先看清这条链,否则会出现"改了不生效"或"改了重启就丢"。

2.1 三层配置链

第 1 层  snikket.conf                ← 你唯一要编辑的文件(env_file 注入四组件)
            │  容器启动时变成进程环境变量
            ▼
第 2 层  各组件镜像内置的启动脚本与配置模板
            │  服务器组件:/etc/prosody/prosody.cfg.lua 模板在 Prosody 加载时
            │  直接求值 ENV_SNIKKET_* 变量(该文件由镜像烘焙,改了重启即丢)
            │  门户组件:hypercorn 启动脚本按变量定监听地址与端口
            │  代理组件:Nginx 模板按变量渲染站点配置
            ▼
第 3 层  运行时生效值                 ← 用 prosodyctl shell config get 查证的就是这层

说明(逐层):

  • 第 1 层:snikket.conf 是普通 KEY=VALUE 文件。官方 compose 用 env_file: snikket.conf 把整份文件注入四个服务,因此一处修改、四组件同时可见。实测四组件的运行时环境变量都带着同一份 SNIKKET_DOMAIN/SNIKKET_ADMIN_EMAIL(回显见 3.2)。
  • 第 2 层:以服务器组件为例,/etc/prosody/prosody.cfg.lua 在镜像构建时烘焙(实测文件时间戳为镜像构建日,容器重建不变),内容即模板源码——开头就断言 ENV_SNIKKET_DOMAIN 必须存在,通篇用 Lua.tonumber(ENV_SNIKKET_RETENTION_DAYS) or 7 这类表达式在配置加载时读取环境变量。所以改参数不需要碰这个文件,改环境变量即可;反过来,直接编辑它是无效的持久化手段。门户组件同理(hypercorn 启动脚本读环境变量决定监听地址与端口),代理组件则是 Nginx 模板经变量渲染生成站点配置。
  • 第 3 层:模板最后一行 Include (ENV_SNIKKET_TWEAK_EXTRA_CONFIG or "/snikket/prosody/*.cfg.lua") 指向数据卷上的扩展目录——这是官方预留的深度定制口子,放进去的 .cfg.lua 会在主模板之后加载,可覆盖任何选项,且随数据卷持久化(实测验证见 3.5)。

💡 技术拓展:配置注入的两种常见方式——

方式原理取舍
env_file 环境变量注入(Snikket 官方采用)变量进进程环境,配置模板加载时求值换参零侵入、四组件天然共享;复杂结构表达力有限
配置文件 bind mount直接挂载最终配置文件表达力强;但多组件各挂各的,容易与模板升级冲突

Snikket 把"模板求值环境变量"做成一层,兼顾两者:日常改动走环境变量,深度定制走 Include 扩展文件,两者都持久、都可升级。

2.2 修改生效规则

官方文档明确:修改 snikket.conf 后必须 docker compose up -d 应用(该命令会检测到环境变量变化并重建受影响的容器)。注意两个易错点:

  • 用 docker compose restart 不会重读 env_file(restart 只是重启进程,环境变量还是旧值),必须 up -d;
  • 服务器组件的存储后端切换涉及数据迁移,首次切换要给足迁移时间(实测约 20~30 秒,见 5.5)。

三、参数查看与修改方式(实测)

3.1 查看当前配置文件

# 配置文件在部署目录(官方约定 /etc/snikket),直接 cat
cat /etc/snikket/snikket.conf

实测回显(测试实例当前内容):

# The domain of your Snikket instance
SNIKKET_DOMAIN=snikket.local

# The email address of the primary admin
SNIKKET_ADMIN_EMAIL=admin@snikket.local

# Site display name and message retention (test)
SNIKKET_SITE_NAME=Snikket test site
SNIKKET_RETENTION_DAYS=14

3.2 查看组件运行时环境变量

确认配置是否真的注入了某个组件,env 最直接。实测四个组件(命令 docker compose exec snikket_server env | grep -E '^(SNIKKET|TWEAK)' | sort,其余组件同理,仅列 SNIKKET/TWEAK 行):

=== server ===
SNIKKET_ADMIN_EMAIL=admin@snikket.local
SNIKKET_DOMAIN=snikket.local
SNIKKET_TWEAK_INTERNAL_HTTP_INTERFACE=0.0.0.0
=== portal ===
SNIKKET_ADMIN_EMAIL=admin@snikket.local
SNIKKET_DOMAIN=snikket.local
SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE=0.0.0.0
SNIKKET_WEB_PROSODY_ENDPOINT=http://snikket_server:5280/
SNIKKET_WEB_PYENV=/etc/snikket-web-portal/env.py
=== proxy ===
SNIKKET_ADMIN_EMAIL=admin@snikket.local
SNIKKET_DOMAIN=snikket.local
SNIKKET_TWEAK_INTERNAL_HTTP_HOST=snikket_server
SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_HOST=snikket_portal
=== certs ===
SNIKKET_ADMIN_EMAIL=admin@snikket.local
SNIKKET_DOMAIN=snikket.local

要点:SNIKKET_SITE_NAME/SNIKKET_RETENTION_DAYS 是实测中刚加入 snikket.conf 并 up -d 的,四个组件都同步可见;portal 额外有镜像内置的 SNIKKET_WEB_PYENV(门户密钥引导脚本路径,见 7.3);proxy 的两个 *_HTTP_HOST 是桥接形态加的互指变量(宿主网络形态不需要,默认 localhost 即正确)。

3.3 查看 Prosody 运行时生效值

服务器组件的配置加载结果用 prosodyctl about 看全貌(配置目录、数据目录、引擎版本):

$ docker compose exec snikket_server prosodyctl about
Prosody trunk nightly build 2079 (2026-05-27, fa492a9d1a20)

# Prosody directories
Data directory:     /snikket/prosody
Config directory:   /etc/prosody
Source directory:   /usr/lib/prosody
Plugin directories:
  /var/lib/prosody/custom_plugins - not a directory!
  /etc/prosody/modules
  /usr/lib/prosody/modules/
  

# Operating system
Linux 7.0.0-38-generic	

# Lua environment
Lua version:             	Lua 5.4

查询单个配置项用 prosodyctl shell config get <域名> <选项名>(输出引号内为生效值):

$ docker compose exec snikket_server prosodyctl shell config get snikket.local storage
OK: "internal"
$ docker compose exec snikket_server prosodyctl shell config get snikket.local site_name
OK: "snikket.local"

3.4 修改参数并验证生效(完整闭环)

以 SNIKKET_SITE_NAME(站点名)与 SNIKKET_RETENTION_DAYS(留存天数)为例,实测一次完整修改:

# 1) 编辑 snikket.conf 追加两行
cat >> /etc/snikket/snikket.conf <<'EOF'

# Site display name and message retention (test)
SNIKKET_SITE_NAME=Snikket test site
SNIKKET_RETENTION_DAYS=14
EOF

# 2) 应用(必须 up -d,restart 不重读 env_file)
cd /etc/snikket && docker compose up -d

实测应用过程回显(up -d 检测到环境变量变化,重建四个容器):

 Container snikket Starting 
 Container snikket-certs Starting 
 Container snikket-portal Started 
 Container snikket-proxy Started 
 Container snikket Started 
 Container snikket-certs Started 

验证(3.3 的查询命令):

$ docker compose exec snikket_server prosodyctl shell config get snikket.local site_name
OK: "Snikket test site"
$ docker compose exec snikket_server prosodyctl shell config get snikket.local archive_expires_after
OK: "14d"
$ docker compose exec snikket_portal env | grep SNIKKET_SITE_NAME
SNIKKET_SITE_NAME=Snikket test site

三处查证全部命中:Prosody 配置项 site_name 由默认值 snikket.local 变为 Snikket test site,留存天数体现在 archive_expires_after(模板表达式 ("%dd"):format(RETENTION_DAYS) 求值结果),门户也拿到了同名变量。

3.5 深度定制:扩展配置文件(实测)

改模板里没有暴露的 Prosody 原生选项时,用第 2.1 节说的扩展点:往数据卷目录 /snikket/prosody/ 放一个 .cfg.lua 文件。实测把单用户多端登录数上限 max_resources(模板默认 10)压到 5:

# 在服务器组件内往数据卷写扩展配置(该目录持久化,重建容器不丢)
docker compose exec snikket_server sh -c 'echo "max_resources = 5" > /snikket/prosody/zz-custom-test.cfg.lua'

# 重启服务器组件使扩展文件被重新 Include
cd /etc/snikket && docker compose restart snikket_server

验证:

$ docker compose exec snikket_server prosodyctl shell config get snikket.local max_resources
OK: 5

默认值 10 被覆盖为 5,扩展点可用。验证完删除测试文件(rm /snikket/prosody/zz-custom-test.cfg.lua)并再次重启即可还原。⚠️ 扩展文件里写的是 Prosody 原生配置语法(不是环境变量),写错会导致服务器组件起不来,改前先备份:docker compose exec snikket_server cp /snikket/prosody/zz-custom-test.cfg.lua /root/。

四、参数总览

下表汇总 snikket.conf 全部已文档化参数(默认值来源:官方 Advanced configuration 文档 + 镜像启动脚本实测)。⚠️ 官方对 TWEAK_ 前缀参数有明确警示:可能破坏你的部署,除非确知用途否则不要设置——表里用风险列区分。

4.1 基础身份(2 个必填)

变量默认值作用风险
SNIKKET_DOMAIN无(必填)实例主域:XMPP 地址后缀、证书签发对象、groups./share. 子域基准。首次启动后不可更改改动=换实例身份
SNIKKET_ADMIN_EMAIL无(必填)管理员邮箱:Let's Encrypt 账户注册邮箱 + 新用户可见的管理员联系方式低

4.2 业务行为(推荐了解)

变量默认值作用风险
SNIKKET_RETENTION_DAYS7消息/上传文件留存天数;调小会立即删除超期消息低
SNIKKET_UPLOAD_STORAGE_GB无限制全实例上传文件总量上限(GB),防磁盘被传爆低
SNIKKET_DAILY_UPLOAD_LIMIT_PER_USER_GB1单用户每日上传配额(GB)低
SNIKKET_LOGLEVELinfo服务器日志级别:error/warn/info/debug;debug 极详尽且含敏感信息、易撑爆磁盘低
SNIKKET_SITE_NAME取 SNIKKET_DOMAIN站点显示名(门户标题、默认群组名)低
SNIKKET_UPDATE_CHECK开启经 DNS 匿名查询新版本并提醒(不暴露 IP/域名);设 0 关闭低
SNIKKET_ABUSE_EMAIL无公开的滥用举报邮箱(XMPP 网络与实例网站可见)低
SNIKKET_SECURITY_EMAIL无公开的安全问题报告邮箱低
SNIKKET_PROXY65_PORT5000内置文件传输代理(大文件 NAT 中继)端口低(改后同步防火墙)
SNIKKET_WEB_AVATAR_CACHE_TTL未公开门户头像的浏览器缓存秒数低

4.3 证书与 TLS

变量默认值作用风险
SNIKKET_TLS_PROFILEmodern聊天连接 TLS 档位:modern/intermediate/old(基于 Mozilla 服务端 TLS 档位)中
SNIKKET_CERTBOT_OPTIONS无certbot 命令行附加参数中
SNIKKET_CERTBOT_KEY_OPTIONS--reuse-key设 --no-reuse-key 则每次续期轮换私钥(会使 DANE/证书监控失效)中
SNIKKET_LETSENCRYPT_TOS_AGREE无官方样例中用于静默同意 LE 服务条款低

4.4 TURN/STUN(音视频通话)

变量默认值作用风险
SNIKKET_TWEAK_TURNSERVER开启设 0 停用内置 TURN(须自备外部 TURN 并配 DOMAIN/SECRET,否则通话全断)高
SNIKKET_TWEAK_TURNSERVER_PORT3478TURN 主监听端口(客户端自动发现新端口)中
SNIKKET_TWEAK_TURNSERVER_MIN_PORT/_MAX_PORT见防火墙文档TURN 中继 UDP 端口范围中
SNIKKET_TWEAK_TURNSERVER_INTERNAL_IP自动探测NAT 后部署时手工指定内网 IP;要求 NAT 保端口号转发高
SNIKKET_TWEAK_TURNSERVER_DOMAIN取 SNIKKET_DOMAIN对外通告的 TURN 主机名(用外部 TURN 时才改)高
SNIKKET_TWEAK_TURNSERVER_SECRET首装自动生成并持久化TURN 客户端认证共享密钥(/snikket/prosody/turn-auth-secret-v2)高

4.5 组件互联(宿主网络默认即正确;桥接改造才需要动)

变量默认值作用风险
SNIKKET_TWEAK_INTERNAL_HTTP_PORT5280Prosody 内部 HTTP API 端口(改它必须同步 SNIKKET_WEB_PROSODY_ENDPOINT)高
SNIKKET_TWEAK_INTERNAL_HTTP_INTERFACE127.0.0.1,::1Prosody HTTP API 监听地址;桥接形态改 0.0.0.0(有未鉴权系统信息暴露面,勿绑公网)高
SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT5765门户内部 HTTP 端口(hypercorn 监听,启动脚本实测默认值)高
SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE127.0.0.1门户内部监听地址(桥接形态改 0.0.0.0)高
SNIKKET_TWEAK_INTERNAL_HTTP_HOSTlocalhostNginx 反代到 Prosody API 的上游主机名高
SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_HOSTlocalhostNginx 反代到门户的上游主机名高
SNIKKET_TWEAK_HTTP_PORT/_HTTPS_PORT80 / 443Nginx 对外监听端口高
SNIKKET_WEB_PROSODY_ENDPOINThttp://127.0.0.1:5280/门户调 Prosody 管理 API(OAuth2 password 授权)的端点高
SNIKKET_TWEAK_WEB_PROXY_PROTOCOLShttp https加载哪些 Nginx 配置模板(http/https,自定义模板用)高
SNIKKET_TWEAK_WEB_PROXY_RELOAD_INTERVAL86400Web 代理重载间隔秒数(捡新证书);inf 关闭自动重载中
SNIKKET_WEB_SECRET_KEY自动生成持久化门户会话密钥(留空即可,见 7.3)高

4.6 存储与实验特性(arcane,非必要勿动)

变量默认值作用风险
SNIKKET_TWEAK_STORAGEfiles存储后端:files(现行默认)/ sqlite(官方称未来可能转正);切换时自动迁移,实测见 5.5高
SNIKKET_TWEAK_EXTRA_CONFIG/snikket/prosody/*.cfg.lua扩展配置文件路径或 glob(实测见 3.5)高
SNIKKET_TWEAK_PROMETHEUS0设 1 后按 Prometheus 抓取节奏采样指标(不开抓取会导致门户系统健康面板异常)中
SNIKKET_TWEAK_IPV6开启设 0 关闭 IPv6(宿主网络形态默认启用且能优雅降级)中
SNIKKET_TWEAK_REQUIRE_SASL20设 1 仅允许 SASL2 客户端连接(大量现役客户端不支持,会拒人)高
SNIKKET_TWEAK_PUSH20Push 2.0 预览开关(尚无客户端支持,仅供开发测试)高
SNIKKET_TWEAK_S2S_STATUS0S2S 连接健康监控模块(目前无界面展示,仅开发用)高
SNIKKET_TWEAK_RESTRICTED_USERS_V20受限用户实现 v2 预览高
SNIKKET_TWEAK_DNSSEC0启用 DNSSEC 验证与 DANE 出站(要求上游解析器支持)高
SNIKKET_TWEAK_SHARE_DOMAIN0把文件共享挂到主域而非 share. 子域(与门户冲突,官方明示勿设)高
SNIKKET_TWEAK_TURNSERVER_INTERNAL_IP 之外的 TWEAK_SNIKKET_BOOTSTRAP_INDEX/_SECRET勿设引导期邀请机制内部参数(官方原文 "Just do not set this")高
SNIKKET_INVITE_URLhttps://<主域>/invite/{invite.token}/邀请链接模板(改动大概率弄坏邀请流)高
SNIKKET_TWEAK_HTTP_TLS_VERSIONS/_CIPHERSMozilla intermediateHTTPS 的 TLS 版本与套件(收紧会拒老浏览器/老系统)高

表格选型要点:4.1/4.2 两张表覆盖日常运维 95% 的调参需求;4.5 只在桥接/反代改造时动(完整改造步骤见《Snikket Docker Compose 部署指南》4.4);4.6 出问题不找官方 support——先还原默认值再说。

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

5.1 SNIKKET_DOMAIN:一次定终身

主域决定四件事:用户 JID 后缀(admin@snikket.local)、三个服务主机名(snikket.local、groups.snikket.local、share.snikket.local——后者在模板中以 "groups."..DOMAIN、"share."..DOMAIN 拼接生成)、证书签发对象、以及 DNS 规划(主域 A 记录 + 两个 CNAME)。首次启动写入数据卷后不可更改:证书目录、群组 MUC 域、用户数据目录都以域名为键(实测数据卷目录名即 URL 转义形式 snikket%2esnikket%2elocal),中途换域等于所有用户账号、群组、历史数据全部失联。要换域只能停服、清卷、重新初始化。

5.2 站点名与联系邮箱

SNIKKET_SITE_NAME 影响门户标题与默认群组名(模板 group_default_name = ENV_SNIKKET_SITE_NAME or DOMAIN),修改闭环实测见 3.4。SNIKKET_ABUSE_EMAIL/SNIKKET_SECURITY_EMAIL 是唯一两个标注 Public 的参数:写入 XMPP 网络标准联系方式(XEP-0157),联邦内其他服务器与实例网站都能看到;SNIKKET_ADMIN_EMAIL 则只发给自己的新用户。对外运营的实例建议三者都填真实可达邮箱。

5.3 消息留存与上传配额

三个配额参数联动,改前先算账:

  • SNIKKET_RETENTION_DAYS(默认 7):消息存档与上传文件共用这条留存线。模板里两处消费:archive_expires_after = ("%dd"):format(RETENTION_DAYS) 与文件过期 http_file_share_expires_after = 60*60*24*RETENTION_DAYS。调小立即删数据(官方原文明确警告);调大只是放宽,已删的回不来。留存的意义是离线设备追消息:设备断网超过留存天数,就永久错过这段消息。
  • SNIKKET_UPLOAD_STORAGE_GB(默认无限):全实例上传总量上限。到顶后所有用户传不了新文件,直到旧行文件过留存期清掉或手动调大。多用户实例建议必设,例如 SNIKKET_UPLOAD_STORAGE_GB=1.5(官方示例值)。
  • SNIKKET_DAILY_UPLOAD_LIMIT_PER_USER_GB(默认 1):单用户单日上传量(官方口径:单文件上限 100MB × 10 倍)。注意留存期拉长会放大实际磁盘占用(文件存得更久),两个参数要一起看。

实测验证(把留存调到 14 天后):prosodyctl shell config get snikket.local archive_expires_after → OK: "14d"(3.4 节回显)。

5.4 TLS 档位与 HTTPS 加密族

💡 技术拓展:服务端 TLS 兼容性档位不是 Snikket 独有概念,Mozilla 维护的三档服务端配置是业界通用基线——

档位取舍典型代价
modern只留 TLS 1.3 与强套件,安全性最高老系统连不上(Android 10+/iOS 12+ 起步)
intermediate强度与兼容平衡少数极老设备仍不可用
old兼容最老设备放弃部分前向安全,官方不推荐

Snikket 默认 modern;聊天连接档位用 SNIKKET_TLS_PROFILE 调,HTTPS(网页侧)另有 SNIKKET_TWEAK_HTTP_TLS_VERSIONS/_CIPHERS(默认 intermediate)。本方案保持默认 modern,未做改动。

只在与老客户端兼容出问题时才需要动这组参数。

5.5 存储后端:files vs sqlite(双向迁移实测)

💡 技术拓展:这是 Snikket 内置的存储引擎二选一——

后端原理取舍
files(默认)每类数据一个小文件(.dat/.list/.lidx),按主机/按用户目录存放实现最简、备份即拷目录;海量小文件在超大规模下检索与inode 开销大
sqlite单文件关系库 prosody.sqlite单文件易备份迁移、大库下查询稳定;写入并发弱于真正的 C/S 数据库

官方标注 sqlite 是 "sneak preview / potential future default"。当前生产保持默认 files 即可;若切换,官方启动脚本自带双向自动迁移(下文实测)。

切换机制(启动脚本逻辑):设 SNIKKET_TWEAK_STORAGE=sqlite 后,容器启动时若发现无 prosody.sqlite,先跑 prosody-migrator files sqlite 把现有数据迁入,成功后自动删除旧文件式数据,失败则删掉半成品 sqlite 并拒绝启动(不会两头数据都不一致)。反向同理。实测全过程:

# 1) snikket.conf 追加一行后 up -d
echo 'SNIKKET_TWEAK_STORAGE=sqlite' >> /etc/snikket/snikket.conf
cd /etc/snikket && docker compose up -d

等待约 30 秒(迁移在启动路径上完成),逐项验证:

$ docker compose exec snikket_server prosodyctl shell config get snikket.local storage
OK: "sql"
$ docker compose exec snikket_server ls -la /snikket/prosody/prosody.sqlite
-rw-r----- 1 prosody prosody 45056 Oct 30 14:58 /snikket/prosody/prosody.sqlite
$ docker compose exec snikket_server prosodyctl shell user list snikket.local
admin@snikket.local
OK: Showing all 1 users

存量用户 admin@snikket.local 完整迁移。删除 sqlite 行回切 files,再次 up -d,验证反向迁移:

$ docker compose exec snikket_server prosodyctl shell config get snikket.local storage
OK: "internal"
$ docker compose exec snikket_server sh -c 'ls /snikket/prosody/ | grep -c sqlite; ls /snikket/prosody/'
0
groups%2esnikket%2elocal
oauth2-registration-secret
prosody.sock
share%2esnikket%2elocal
snikket%2elocal
turn-auth-secret-v2
$ docker compose exec snikket_server prosodyctl shell user list snikket.local
admin@snikket.local
OK: Showing all 1 users

sqlite 文件消失(计数 0)、按域目录恢复、用户无损。结论:双向迁移可放心用,但迁移期间会有启动等待,且迁移成功即删旧格式数据——回切依赖迁移器再次工作,生产切换前先备份 /snikket/prosody/。

5.6 TURN/STUN 组:音视频通话的命门

内置 coturn 默认开启,客户端自动发现,正常情况一个参数都不用配。三种必须动的场景:

  1. 改 TURN 端口:SNIKKET_TWEAK_TURNSERVER_PORT=3478 以外的端口(端口被占时),客户端会自动跟随新端口,防火墙同步放行;
  2. 中继端口范围:SNIKKET_TWEAK_TURNSERVER_MIN_PORT/MAX_PORT 控制媒体中继的 UDP 段,防火墙按段放行;
  3. NAT 后部署:SNIKKET_TWEAK_TURNSERVER_INTERNAL_IP 指定内网 IP,且要求 NAT 严格保端口号映射(官方原文大写强调 MUST)。实测桥接(NAT)形态下 coturn 因探测不到公网 IP 拒绝启动的完整排障实录见《Snikket Docker Compose 部署指南》8.2——这也是官方默认推荐宿主网络直绑的原因之一。

自备外部 TURN 时:SNIKKET_TWEAK_TURNSERVER=0 + SNIKKET_TWEAK_TURNSERVER_DOMAIN=<外部TURN主机名> + SNIKKET_TWEAK_TURNSERVER_SECRET=<共享密钥> 三件套缺一不可,漏配后果是用户音视频通话全断。

5.7 证书参数

SNIKKET_CERTBOT_OPTIONS 透传给 certbot(如需要指定 DNS 插件、RAQN 等);SNIKKET_CERTBOT_KEY_OPTIONS 默认 --reuse-key(续期不换私钥,对 DANE 与证书监控友好),设 --no-reuse-key 每次续期轮换。证书链路机制(cert-manager 签发 → 服务器组件导入 → Web 代理定时重载捡新证书)见《Snikket stable.20260611.1 常用运维命令与排障详解》证书一节。

5.8 组件互联参数:何时需要动

宿主网络形态(官方默认)下,proxy/portal/server 三个组件同处一个网络栈,localhost:5280/localhost:5765 互指天然成立,这组参数一个都不用配。只有改造网络形态(桥接、自定义网络)时才需要三组联动:Prosody HTTP API 监听 0.0.0.0、门户监听 0.0.0.0、proxy 两个上游主机名改服务名、portal 的 SNIKKET_WEB_PROSODY_ENDPOINT 改 http://snikket_server:5280/。完整可复制的改造 compose 与实测验证(健康检查、管理员登录、XMPP C2S 全链路)见《Snikket Docker Compose 部署指南》4.4 节。

六、生产配置模板

一份带注释的生产 snikket.conf(/etc/snikket/snikket.conf),按需删减:

cat > snikket.conf <<'EOF'
# ===== 必填 =====
# 实例主域:JID 后缀/证书对象/子域基准,首次启动后不可更改
SNIKKET_DOMAIN=chat.example.com
# 管理员邮箱:LE 账户注册 + 新用户可见联系方式
SNIKKET_ADMIN_EMAIL=admin@example.com

# ===== 强烈建议 =====
# 站点显示名(默认取主域)
SNIKKET_SITE_NAME=Example Chat
# 消息/文件留存天数(默认 7;调小会立即删除超期数据)
SNIKKET_RETENTION_DAYS=14
# 全实例上传总量上限 GB(默认无限,多用户实例必设)
SNIKKET_UPLOAD_STORAGE_GB=50
# 公开联系邮箱(对外运营建议都填)
SNIKKET_ABUSE_EMAIL=abuse@example.com
SNIKKET_SECURITY_EMAIL=security@example.com

# ===== 按需 =====
# 日志级别:error/warn/info/debug(debug 含敏感信息且易撑爆磁盘)
#SNIKKET_LOGLEVEL=info
# 聊天连接 TLS 档位:modern/intermediate/old(老设备连不上再降)
#SNIKKET_TLS_PROFILE=intermediate
# 关闭匿名更新检查(默认开启,经 DNS 匿名查询,不暴露实例信息)
#SNIKKET_UPDATE_CHECK=0
# 同意 Let's Encrypt 服务条款(静默续期用)
#SNIKKET_LETSENCRYPT_TOS_AGREE=Y
EOF

应用并验证:

cd /etc/snikket && docker compose up -d

逐项验证(抽查关键值):

$ docker compose exec snikket_server prosodyctl shell config get chat.example.com site_name
OK: "Example Chat"
$ docker compose exec snikket_server prosodyctl shell config get chat.example.com archive_expires_after
OK: "14d"

模板取舍说明:只收 4.1/4.2/4.3 三个低风险表的参数;TURN 与组件互联保持默认(宿主网络形态开箱即用);TWEAK_STORAGE/SNIKKET_WEB_SECRET_KEY 等高风险项一律不进模板——默认值即最优值,动了才需要写进配置。

七、常见问题

7.1 改了 snikket.conf 不生效

按顺序排查:① 用的是 docker compose restart 还是 up -d——restart 不重读 env_file,必须 up -d(官方文档原话:After modifying any options in snikket.conf, you must run 'docker compose up -d');② 配置键拼写错误(变量名拼错不报错,只是当没写);③ 确认组件真的重建了:docker compose up -d 的输出里应有 Recreate/Started 字样而非全部 Running;④ 最终以 prosodyctl shell config get <域> <项> 的运行时值为准,而不是以配置文件内容为准。

7.2 想改主域 SNIKKET_DOMAIN,有办法吗

没有受支持的就地改法。域名是数据卷内一切数据的组织键(证书目录、用户数据目录 snikket%2e<域>、群组域、OAuth2 密钥作用域都含域名),改域=换实例。受支持路径:备份用户数据(如需要)→ 停栈 → 清空数据卷重新初始化 → 用户重新注册。若只是"域名没备案要换入口",正确做法是换 DNS 解析而不是改 SNIKKET_DOMAIN。

7.3 SNIKKET_WEB_SECRET_KEY 需要自己生成吗

不需要。门户启动引导脚本 /etc/snikket-web-portal/env.py 实测逻辑:环境变量里没有时,优先从 /etc/snikket-web-portal/secret_key 恢复,文件也没有则随机生成并落盘持久化。注意该文件在容器层而非数据卷——重建门户容器会生成新密钥,表现为所有已登录会话失效(重新登录即可,无数据损失)。若要求会话跨重建稳定,可在 compose 的 portal 服务里显式注入 SNIKKET_WEB_SECRET_KEY(自定义随机串)并纳入备份。

7.4 TWEAK_ 参数到底能不能用

能用,但官方警示原话是 "Some of these options may break your setup"(有些选项可能弄坏你的部署)且"仅在此处记录的选项不保证跨版本行为不变"。实操守则:每次只动一个 TWEAK 项 → up -d → 验证(健康检查 + 客户端连接)→ 留档;出问题第一步永远是删掉该行还原默认。TWEAK_SNIKKET_BOOTSTRAP_INDEX/_SECRET 与 SNIKKET_TWEAK_SHARE_DOMAIN 两项官方明示勿设,直接跳过。

7.5 sqlite 切换会不会丢数据

实测不丢(5.5 节双向迁移全程用户无损),但机制上有两个窗口期:迁移失败时启动脚本会删除半成品 sqlite 后拒绝启动(fail-fast,不会带病运行);迁移成功后旧格式数据即被清理。所以:切换前备份 /snikket/prosody/;切换后等 prosodyctl shell user list 确认用户齐全再收工。

八、参考链接