ejabberd 26.09 配置参数详解
ejabberd 26.09 配置逐节实测:dump_config/reload_config 查改闭环、宏环境变量覆盖、SQLite 切换对照、自签证书替换、ACL 增补管理员与生产模板,附单文件挂载排障实录。
ejabberd 26.09 配置参数详解
目标:逐节讲透 ejabberd 26.09 主配置文件
ejabberd.yml的核心参数——hosts、日志、证书与 ACME、监听器、s2s 联邦、认证、数据库、ACL 与访问规则、流控、模块——每节配真实修改动作与实测回显,并给出生产配置模板;全部操作在 Ubuntu 22.04.4 LTS 部署的 ejabberd 26.09 上实测通过。
一、环境信息
本章记录实测环境,正文所有命令与回显均出自该环境。
- 操作系统:Ubuntu 22.04.4 LTS(x86_64);
- ejabberd:26.09(官方
ejabberd/ecs:26.09部署,部署过程见 《Docker Compose 部署 ejabberd 指南》); - 配置文件:
/srv/ejabberd/conf/ejabberd.yml(宿主)→ 容器内/opt/ejabberd/conf/ejabberd.yml(即/home/ejabberd/conf/ejabberd.yml,两路径同一文件),共 339 行,含完整官方注释; - 管理账号:
admin@localhost/q1w2e3r4,另实测增补ops@localhost; - 配置目录同时含:
ejabberdctl.cfg(ejabberdctl 脚本行为)、server.pem(TLS 证书)、cacert.pem(CA 信任库)、dhparams.pem(DH 参数)、inetrc(DNS 解析配置)。
二、前置条件
按 《Docker Compose 部署 ejabberd 指南》第四章完成部署并确认服务在跑;本文配置目录以整目录方式挂载(./conf:/opt/ejabberd/conf:ro),管理员账号可正常登录 WebAdmin:
docker exec ejabberd-26.09-main ejabberdctl status
实测回显:
The node ejabberd@localhost is started with status: started
ejabberd 26.9.0 is running in that node
⚠️ 注意:若你的部署把配置文件以单文件方式挂载(
./conf/ejabberd.yml:/opt/ejabberd/conf/ejabberd.yml:ro),宿主上用sed -i/vim 等「替换文件」的编辑器改配置后,容器内读到的仍是旧 inode 的内容——这是单文件 bind mount 的经典陷阱,实测踩中过(详见第七章 FAQ Q1)。本文所有实测基于整目录挂载,推荐读者也用整目录挂载。
三、参数查看与修改方式
改参数之前先解决两个问题:怎么看到「当前真正生效」的配置;改完后怎么让新配置生效。本章四种手段全部实测。
3.1 查看:dump_config 导出运行时配置
ejabberdctl dump_config <输出文件> 把 ejabberd 眼中实际生效的完整配置导出为 YAML——所有宏已展开、所有默认值已填充,是排查「我改的配置为什么没生效」的第一工具:
docker exec ejabberd-26.09-main ejabberdctl dump_config /opt/ejabberd/database/dump-live.yml
head -8 /srv/ejabberd/database/dump-live.yml
实测回显(输出节选):
hosts:
- "localhost"
loglevel: info
certfiles:
- /home/ejabberd/conf/server.pem
ca_file: "/home/ejabberd/conf/cacert.pem"
listen:
-
port: 5222
对比源文件与导出文件可见:源文件里 listen 段写的是宏 PORT_C2S,导出文件里已展开为 5222——宏机制只存在于源文件层,运行时全部落地为实值。
3.2 修改与热重载:reload_config
ejabberdctl reload_config 重读配置文件并应用,多数参数热生效无需重启。实测闭环:把日志级别从 info 改为 warning,热重载后用 dump_config 确认:
sed -i 's/^loglevel: info/loglevel: warning/' /srv/ejabberd/conf/ejabberd.yml
docker exec ejabberd-26.09-main ejabberdctl reload_config
docker exec ejabberd-26.09-main ejabberdctl dump_config /opt/ejabberd/database/dump-check.yml
grep '^loglevel' /srv/ejabberd/database/dump-check.yml
实测回显:
loglevel: warning
⚠️ 实测注意:并非所有参数都能热重载。实测
loglevel、acl、access_rules、modules、SQL 数据库参数均可热生效;certfiles的文件清单变更实测未随 reload 生效(证书内容变更可热重载),需要重启服务:
docker compose restart ejabberd
3.3 环境变量宏覆盖:EJABBERD_MACRO_*
自 24.12 起,ejabberd 启动时读取 EJABBERD_MACRO_<名字> 环境变量,覆盖 define_macro 中同名宏。实测:给服务注入 EJABBERD_MACRO_HOST=chat.example.org 后重启,导出配置确认:
environment:
- EJABBERD_MACRO_HOST=chat.example.org
docker compose up -d --force-recreate
docker exec ejabberd-26.09-main ejabberdctl dump_config /opt/ejabberd/database/dump-macro.yml
grep -A2 '^hosts' /srv/ejabberd/database/dump-macro.yml
实测回显:
hosts:
- "chat.example.org"
源文件 define_macro 里 HOST: localhost 未动,环境变量把它覆盖成 chat.example.org。这套机制让「同一份配置文件 + 不同环境变量」服务多套环境(测试/生产)成为可能。实测完成后移除该变量并重建,恢复 localhost 域。
3.4 修改生效方式对比
| 方式 | 命令 | 生效参数范围 | 会话影响 |
|---|---|---|---|
| 热重载 | ejabberdctl reload_config | 多数运行参数(日志/ACL/模块/数据库) | 在线会话不断开 |
| 重启服务 | docker compose restart ejabberd | 全部(含 certfiles 清单) | 在线会话断开重连 |
| 重建服务 | docker compose up -d --force-recreate | 全部 + 挂载/环境变量变更 | 同上,且重建工作负载 |
| 模块级重启 | ejabberdctl restart_module <域名> <模块> | 单个模块 | 仅该模块功能短暂中断 |
选型建议:日常调参先 reload_config,验证手段统一用 dump_config 看运行时值;改监听端口、证书清单、环境变量这类「启动期参数」才走重启。
四、参数总览
一份 ejabberd.yml 的结构地图如下,按「全局 → 监听 → 存储与认证 → 权限 → 模块」五层组织:
| 配置段 | 层级 | 作用 | 默认值(ecs 26.09) |
|---|---|---|---|
define_macro | 全局 | 定义宏变量,全文引用 | HOST=localhost、ADMIN=admin@localhost、各端口宏 |
hosts | 全局 | 本服务器服务的 XMPP 域名列表 | - HOST(即 localhost) |
loglevel | 全局 | 日志级别 | info |
certfiles / ca_file | 全局 | TLS 证书与 CA 信任库 | /home/ejabberd/conf/server.pem、cacert.pem |
acme | 全局 | Let's Encrypt 自动证书 | staging CA + mailto 占位 |
listen | 监听 | 各协议监听器 | 5222/5223(c2s)、5269(s2s)、5280/5443/1880(http)、5478(stun)、1883(mqtt)、7777(proxy65) |
s2s_use_starttls | 监听 | 服务器联邦 TLS 策略 | optional |
auth_method | 认证 | 认证后端 | internal(默认,Mnesia 内置) |
default_db / sql_* | 存储 | 持久化后端 | Mnesia(不写即默认) |
acl | 权限 | 访问主体分组 | local/loopback/admin 三组 |
access_rules | 权限 | 把 ACL 组映射到具体权限 | local/c2s/announce/configure 等 |
api_permissions | 权限 | 管理命令的调用方授权 | console/webadmin/adhoc/http/public 五条 |
shaper / shaper_rules | 权限 | 流量整形 | normal=3000B/s、fast=100000B/s |
modules | 模块 | 功能模块启停与参数 | 40+ 个模块 |
💡 说明:
define_macro宏不是普通 YAML 语法而是 ejabberd 扩展,解析发生在 YAML 之前;宏让「域名、端口、管理员」这类跨段复用的值改一处即全局生效。
五、核心参数分类详解
以下每节都遵循「参数含义 → 实际修改动作 → 实测回显 → 要点」的闭环。修改动作均在实测环境真实执行。
5.1 hosts:服务域名
hosts 声明本服务器对外服务的 XMPP 域(用户 JID 的 @ 后缀),是最基础的参数:
hosts:
- HOST
生产改法(假设域名 chat.example.com):
define_macro:
HOST: chat.example.com
ADMIN: "admin@chat.example.com"
hosts:
- HOST
要点:改 HOST 必须同步改 ADMIN 宏(管理员 JID 含域);已有账号绑定旧域,改域后需重新注册或用迁移命令(ejabberdctl help accounts 中的账号命令均带域参数)。ecs 默认配置用宏引用而非硬编码域名,就是为了把这类联动收敛到宏定义一处。
5.2 loglevel:日志级别
顶层 loglevel 控制 ejabberd.log 的详细度,实测验证过 info ↔ warning 双向热切换(3.2 节闭环)。可选级别与取舍:
| 级别 | 内容 | 适用 |
|---|---|---|
debug | 协议包级明细,日志量巨大 | 深度排障,短期 |
info | 启动、会话、模块事件 | 默认,生产可用 |
warning | 仅告警与错误 | 长期稳定运行降噪 |
日志文件位置:/opt/ejabberd/logs/(挂载到宿主 /srv/ejabberd/logs/),默认两类——ejabberd.log(主日志)与 error.log(错误),外加 crash.log(崩溃转储,按需出现)。日志轮转参数(log_rotate_size/log_rotate_count/log_rotate_date)默认按日期轮转,大流量场景建议显式设 log_rotate_size。
5.3 certfiles 与 ACME:TLS 证书
certfiles 是证书文件路径列表,支持通配,ejabberd 按「证书 SAN 与域名匹配」自动分发到各监听器:
certfiles:
- /home/ejabberd/conf/server.pem
ca_file: "/home/ejabberd/conf/cacert.pem"
实测一:换成自签证书。 生成包含 localhost 与会议子域 SAN 的自签证书,改 certfiles 指向后重启:
openssl req -x509 -newkey rsa:2048 -keyout ejabberd.key -out server2.pem -days 365 -nodes \
-subj '/CN=localhost' -addext 'subjectAltName=DNS:localhost,DNS:conference.localhost'
cat ejabberd.key >> server2.pem
# certfiles 指向 server2.pem 后重启
docker compose restart ejabberd
验证实际下发的证书(XMPP STARTTLS 握手):
echo QUIT | timeout 8 openssl s_client -connect 127.0.0.1:5222 -starttls xmpp -xmpphost localhost 2>&1 | grep -E 'subject|Verification'
实测回显(替换前):
subject=C = FR, ST = Paris, L = Paris, O = ProcessOne, OU = IT, CN = localhost
Verification error: self-signed certificate
实测回显(替换后):
subject=CN = localhost
Verification error: self-signed certificate
subject 从镜像自带证书的 O = ProcessOne 组织字段变为新证书仅有的 CN = localhost,确认 certfiles 切换生效。
实测二:ACME 自动证书。 默认配置自带 ACME 段(指向 Let's Encrypt staging 测试环境):
acme:
contact: "mailto:example-admin@example.com"
ca_url: "https://acme-staging-v02.api.letsencrypt.org/directory"
生产启用三步:① contact 改为真实邮箱;② ca_url 改为正式环境 https://acme-v02.api.letsencrypt.org/directory;③ 确保服务器 80/443 可达公网(ACME HTTP-01 验证)。配套管理命令实测可用:
docker exec ejabberd-26.09-main ejabberdctl help acme
实测回显(输出节选):
acme
list_certificates request_certificate revoke_certificate
⚠️ 注意:内网或无公网 80 端口的部署用不了 ACME HTTP-01,走自签 + 客户端信任或购买证书即可;
list_certificates在未启用 ACME 时输出为空属正常。
5.4 listen:监听器全家桶
listen 是端口矩阵,每项一个监听器。ecs 默认配置的完整清单(已实测在容器内监听):
| 端口 | module | 用途 | 关键参数 |
|---|---|---|---|
| 5222 | ejabberd_c2s | 客户端明文口(STARTTLS) | starttls_required: true 强制升级加密 |
| 5223 | ejabberd_c2s | 客户端直连 TLS 口 | tls: true |
| 5269 | ejabberd_s2s_in | 服务器联邦入口 | max_stanza_size: 524288 |
| 5280 | ejabberd_http | WebAdmin(HTTP) | request_handlers /admin |
| 5443 | ejabberd_http | TLS 综合口 | /admin /api /bosh /captcha /upload /oauth /websocket 七个处理器 |
| 1880 | ejabberd_http | 管理台根路径(桌面环境友好) | request_handlers / |
| 5478/UDP | ejabberd_stun | STUN/TURN(音视频打洞) | use_turn + 端口区间 50000-50099 |
| 1883 | mod_mqtt | MQTT 接入 | backlog 1000 |
| 7777 | mod_proxy65 | SOCKS5 文件传输代理 | access: local |
三个最高频的改动:
① 关闭不用的口(最小暴露面,如禁联邦)——直接删除 5269 监听器段并重启;
② 调整客户端口的 TLS 策略——starttls_required: STARTTLS_REQUIRED 宏展开为布尔 true,生产保持强制:
-
port: PORT_C2S
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
starttls_required: STARTTLS_REQUIRED
逐项说明:ip: "::" 双栈监听;max_stanza_size 单个 XML stanza 上限(262144 字节,防超大包攻击);shaper 绑定流量整形规则(见 5.10);access 绑定访问规则名(见 5.8)。
③ 加 REST API 口(运维自动化用)——在 5443 的 request_handlers 里已有 /api: mod_http_api,若要在 5280 明文口也开 API,加一行 /api: mod_http_api 并重启。
5.5 s2s:服务器联邦参数
联邦(与其他 XMPP 域互通)相关参数集中在 s2s_* 前缀,默认配置启用一组关键项:
s2s_use_starttls: optional
实测环境下的联邦开关组合:
| 参数 | 取值 | 含义 |
|---|---|---|
s2s_use_starttls | optional / required / false | 联邦 TLS:可选升级 / 强制 / 关闭 |
s2s_access | 规则名 | 联邦访问控制(默认 all 放行) |
s2s_timeout | 毫秒 | 联邦连接超时 |
⚠️ 注意:关闭联邦不只是删 5269 监听器,还应设置
s2s_access拒绝出站,两者配合才完整。内网私有部署建议s2s_use_starttls: required且仅在确需跨域时开放 5269。
5.6 认证:auth_method
auth_method 指定账号验证后端,默认 internal(账号存本库,register 命令写入)。可选后端一览:
💡 技术拓展:认证后端不止内置一种,常见选项对比——
后端 写法 适用场景 internal(默认) 不配置或 auth_method: internal独立部署,账号自管 sql auth_method: sql+ default_db/sql_*账号存 MySQL/PG/SQLite ldap auth_method: ldap+ ldap_* 段对接企业 AD/OpenLDAP,只读验证 anonymous auth_method: anonymous免注册临时会话(访客场景) jwt auth_method: jwt+ jwt_key外部系统签发令牌直登 本文部署为独立内网环境,采用默认 internal;企业已有 AD/LDAP 时优先 ldap 免去账号双写。
多后端可共存(列表形式),ejabberd 按序尝试。改认证后端后 register/check_password 行为随之后端变化——实测 LDAP 后端时 register 会拒绝写账号(LDAP 只读),这是验证后端切换是否生效的快速手段。
5.7 数据库:default_db 与 sql_*(实测切换)
默认全部数据存 Mnesia(零依赖)。切到 SQL 后端的核心三参数(实测以 SQLite 验证,MySQL/PostgreSQL 写法同类):
default_db: sql
sql_type: sqlite
sql_database: /opt/ejabberd/database/ejabberd-sqlite.db
实测全程记录:在运行中的服务追加以上三行 → reload_config 热切换 → 日志出现建库过程:
2026-10-21 09:00:20.584 [info] Storing sqlite database for host localhost in file /opt/ejabberd/database/ejabberd-sqlite.db
2026-10-21 09:00:20.585 [error] SQL query 'select version from schema_version where module='ejabberd_auth_sql'' failed: ~c"no such table: schema_version"
2026-10-21 09:00:20.587 [info] Creating :sqlite table schema_version
首查 schema_version 报 no such table 是首次建库的正常路径(先查版本表不存在→创建),紧随其后自动建齐全部表。此时验证账号视角的隔离效果:
docker exec ejabberd-26.09-main ejabberdctl register tester localhost test123456
docker exec ejabberd-26.09-main ejabberdctl registered_users localhost
实测回显(SQLite 后端下):
User tester@localhost successfully registered
tester
新注册的 tester 落在 SQLite;切回 Mnesia(删除三行配置再 reload_config)后:
docker exec ejabberd-26.09-main ejabberdctl registered_users localhost
实测回显:
admin
原 Mnesia 库的 admin 原样还在,SQLite 库里的 tester 也不丢——两套后端数据完全独立,切换不是迁移。要把旧数据搬过去用 ejabberdctl export_db(导出 SQL)后再导入。
生产建议(写明场景):default_db: sql + PostgreSQL 适合「万级用户以上、MAM 消息存档长期保留」的主机(官方在默认配置 mod_mam 注释中也明确建议 SQL 后端——Mnesia 有 2GB 上限且易损);SQLite 适合小型独立部署;MySQL 折中。sql_server/sql_database/sql_username/sql_password 四参数用于外部数据库连接。
5.8 acl 与 access_rules:权限双件套
acl 定义「主体集合」,access_rules 把集合映射到权限,两层解耦。默认配置:
acl:
local:
user_regexp: ""
loopback:
ip:
- 127.0.0.0/8
- ::1/128
admin:
user:
- ADMIN
access_rules:
local:
allow: local
c2s:
deny: blocked
allow: all
announce:
allow: admin
configure:
allow: admin
muc_create:
allow: local
pubsub_createnode:
allow: local
trusted_network:
allow: loopback
逐项说明:acl.local 正则匹配所有本域注册用户;acl.loopback 限回环地址;acl.admin 引用 ADMIN 宏。access_rules 里 configure(管理台改配置)、announce(全站广播)只给 admin;muc_create 允许本域用户建群聊房;trusted_network 只含回环——这就是默认配置下 mod_register 的 ip_access: trusted_network 只允许本机自助注册的原因。
实测:增补第二个管理员。 在 acl.admin 追加 ops@localhost 并热重载:
admin:
user:
- ADMIN
- ops@localhost
docker exec ejabberd-26.09-main ejabberdctl register ops localhost q1w2e3r4
curl -s -o /dev/null -w '%{http_code}\n' -u 'ops@localhost:q1w2e3r4' http://127.0.0.1:8143/admin/server/localhost/
实测回显:
User ops@localhost successfully registered
200
ops 账号注册即获得 WebAdmin 服务器管理页访问权(HTTP 200),全程无需重启。ACL 主体写法速查:user:(单个 JID)、user_regexp:(正则)、ip:(网段)、all(内置,人人)。
5.9 api_permissions:管理命令授权
ejabberd 的每个管理命令(ejabberdctl/WebAdmin/REST API 共用同一命令池)由 api_permissions 决定「谁能从哪个通道调什么」:
api_permissions:
"console commands":
from: ejabberd_ctl
who: all
what: "*"
"webadmin commands":
from: ejabberd_web_admin
who: admin
what: "*"
"http access":
from: mod_http_api
who:
access:
allow:
- acl: loopback
- acl: admin
oauth:
scope: "ejabberd:admin"
access:
allow:
- acl: loopback
- acl: admin
what:
- "*"
- "!stop"
- "!start"
"public commands":
who:
ip: 127.0.0.1/8
what:
- status
- connected_users_number
逐项说明:本机 ejabberdctl 全放行(console commands);WebAdmin 仅 admin 组;REST API(http access)仅回环与 admin 组可调,且显式排除 stop/start(! 前缀即排除);public commands 允许本机匿名查状态。给自动化系统开 API 时,照 http access 的模式加 ACL 限定来源 IP,并按需收紧 what 清单——这是官方默认就示范的最佳实践。
5.10 shaper:流量整形
shaper 定义速率(字节/秒),shaper_rules 决定谁套哪种速率:
shaper:
normal:
rate: 3000
burst_size: 20000
fast: 100000
shaper_rules:
max_user_sessions: 10
max_user_offline_messages:
5000: admin
100: all
c2s_shaper:
none: admin
normal: all
s2s_shaper: fast
逐项说明:normal 限 3000 字节/秒、允许 20000 字节突发;c2s_shaper 规则「管理员不限速、普通用户走 normal」;max_user_sessions: 10 单账号最多 10 并发会话(多端登录上限);max_user_offline_messages 离线消息上限按身份分档(admin 5000 条、普通 100 条)。文件传输类流量(proxy65)走 fast 档。高并发消息推送场景把 rate 上调或给推送账号建专用 ACL 走 none。
5.11 modules:模块启停
modules 段列启用模块,ecs 默认启用 40+ 个。三类典型改法:
modules:
mod_adhoc: {}
mod_mam:
db_type: sql
assume_mam_usage: true
default: always
mod_muc:
access:
- allow
access_admin:
- allow: admin
access_create: muc_create
default_room_options:
mam: true
mod_register:
ip_access: trusted_network
mod_version:
show_os: false
逐项说明:空映射 {} 表示全默认;mod_mam 的 db_type: sql 单独指定消息存档走 SQL(官方注释建议——Mnesia 有 2GB 上限);default: always 默认为所有会话存档;mod_muc 的 access_create: muc_create 把建房权交给 5.8 定义的规则;mod_register.ip_access: trusted_network 收紧自助注册来源;mod_version.show_os: false 不泄露操作系统版本(安全加分项)。
模块的在线装卸(不占 modules 段的 contrib 社区模块):
docker exec ejabberd-26.09-main ejabberdctl modules_available | head -5
docker exec ejabberd-26.09-main ejabberdctl module_install <模块名>
六、生产配置模板
适用场景:8GB 内存 / SSD 磁盘 / 千人级企业内部 IM,账号对接外部 PostgreSQL,开启联邦。在默认配置基础上聚焦差异项:
define_macro:
HOST: chat.example.com
ADMIN: "admin@chat.example.com"
STARTTLS_REQUIRED: true
hosts:
- HOST
loglevel: warning
certfiles:
- "/etc/letsencrypt/live/chat.example.com/fullchain.pem"
- "/etc/letsencrypt/live/chat.example.com/privkey.pem"
acme:
contact: "mailto:it-admin@example.com"
ca_url: "https://acme-v02.api.letsencrypt.org/directory"
default_db: sql
sql_type: pgsql
sql_server: "10.0.0.8"
sql_database: "ejabberd"
sql_username: "ejabberd"
sql_password: "从内部密钥管理下发的强口令"
s2s_use_starttls: required
shaper_rules:
max_user_sessions: 20
c2s_shaper:
none: admin
normal: all
modules:
mod_mam:
db_type: sql
default: always
mod_muc:
access_create: muc_create
default_room_options:
mam: true
mod_register:
ip_access: trusted_network
mod_fail2ban: {}
mod_version:
show_os: false
模板要点:域名/管理员收敛进宏;日志降噪 warning;证书指向 ACME 正式目录(ACME 段留作自动续期);数据与 MAM 全走外部 PostgreSQL(8GB 内存主机给 PostgreSQL 分 2GB 足够千人级);联邦强制 TLS;登录口令必须换掉演示值——生产口令经密钥管理下发,不落明文。
七、常见问题(FAQ)
Q1:宿主改了 ejabberd.yml,容器里 reload_config 后还是旧行为?
实测现象:宿主 sed -i 修改配置、执行 reload_config,dump_config 看到的仍是旧值。定位:部署用了单文件 bind mount,sed -i/vim 以「写临时文件再改名」方式保存,文件 inode 变了,容器挂载仍指向旧 inode(实测宿主 inode 9191669 vs 容器内 9191601)。解决:改用整目录挂载(./conf:/opt/ejabberd/conf:ro)后重建服务;目录挂载下文件替换对容器立即可见。顺带提醒:不要用 sed ... | tee 同一文件 的管道就地改——读写同一文件并发会把文件清空(实测踩中,文件变 0 字节),先写临时文件再 mv。
Q2:reload_config 后 certfiles 的新文件路径不生效?
实测确认:certfiles 清单变更需要重启(docker compose restart ejabberd)才加载新路径;已有路径下的证书内容更新可以热重载。判定技巧:证书替换后用 openssl s_client 看 subject 是否变化(5.3 节实测手法)。
Q3:切 SQL 后 registered_users 变空了,数据丢了吗?
没丢。5.7 节实测证明 Mnesia 与 SQL 是两套独立存储,切换视角后各自可见各自账号。找回旧数据:切回 default_db 原值即见原账号;正式迁移用 ejabberdctl export_db。
Q4:SQLite 首次切换时日志报 no such table: schema_version 错误?
首次建库的正常现象:ejabberd 先查 schema 版本表→不存在→自动创建全部表结构(5.7 节回显完整记录了这条路径)。后续重启不再出现;若反复出现且表建不出来,检查 sql_database 路径目录属主是否为容器内 ejabberd 账号(UID 9000)。
Q5:改了宏但好像没生效?
按优先级排查:环境变量 EJABBERD_MACRO_* 覆盖配置文件 define_macro(3.3 节实测 hosts 被 env 覆盖为 chat.example.org);宏名大小写敏感;宏定义必须在引用之前。最终以 dump_config 导出值为准——它反映宏展开后的运行时真相。
八、参考链接
- 官方配置文档总览:https://docs.ejabberd.im/admin/configuration/
- 官方文件格式与宏说明:https://docs.ejabberd.im/admin/configuration/file-format/
- 官方数据库配置文档:https://docs.ejabberd.im/admin/configuration/database/
- 官方 ACME 配置文档:https://docs.ejabberd.im/admin/configuration/basic/#acme
- 官方监听器文档:https://docs.ejabberd.im/admin/configuration/listen/
- 官方 acl/access 文档:https://docs.ejabberd.im/admin/configuration/access/
- 官方模块文档:https://docs.ejabberd.im/admin/configuration/modules/
- 同系列部署篇:《Docker Compose 部署 ejabberd 指南》
- 同系列命令篇:《ejabberd 常用 CLI 命令详解》
- 版本来源:https://github.com/processone/ejabberd/releases.atom(26.09,查询日期 2026-10-21)