WildDuck 1.46 配置参数详解
WildDuck 1.46 三层配置体系完整拆解:wild-config TOML 格式、@include 指令、环境变量覆盖、运行时 API 修改;逐节详解进程/数据库/IMAP/POP3/API/TLS/DKIM 等核心参数及生产推荐值。
WildDuck 1.46 配置参数详解
目标:本文档完整拆解 WildDuck 1.46 的配置体系——wild-config TOML 格式、@include 指令、环境变量覆盖、运行时 API 修改的三层配置模型,逐节详解生产常用参数及其取值边界。信息源自官方配置文档和源码 default.toml(查询日期 2026-10-27)。
一、环境信息
- WildDuck 版本:1.46.1
- 配置框架:wild-config(TOML + @include 合并)
- 配置文件位置:源码仓库
config/目录或自定义路径通过--config指定 - 环境变量前缀:
APPCONF_(Docker 和 systemd 覆盖配置) - 运行时配置 API:
GET /settings/PUT /settings/:key(部分参数无需重启)
二、前置条件
- 已完成 WildDuck 安装(详见 《Ubuntu 22.04 安装 WildDuck 1.46.1 指南》)
- 具备读取和编辑 TOML 配置文件的工具(
vim/nano/VSCode) - 理解 TOML 基础语法(
[section]节头、key = value键值对、字符串需引号)
三、参数查看与修改方式
3.1 配置体系三层模型
WildDuck 的配置遵循「默认值 → 文件覆盖 → 环境变量覆盖」的合并顺序:
┌──────────────────────────────────────────────────────────────┐
│ WildDuck 配置优先级(低→高) │
│ │
│ ① 内置默认值(wild-config 硬编码) │
│ ↓ 合并 │
│ ② config/default.toml(仓库内默认配置,被 @include 引用) │
│ ↓ 合并 │
│ ③ 自定义配置文件(--config=/etc/wildduck.toml,只写需修改项) │
│ ↓ 合并 │
│ ④ APPCONF_* 环境变量(Docker/systemd 环境注入,最高优先级) │
└──────────────────────────────────────────────────────────────┘
💡 技术拓展:wild-config 与传统配置方案的差异——传统 TOML/YAML 加载器是「后到者全量覆盖」,wild-config 采用 递归深合并(deep merge):section 级覆盖时,未指定的 key 保留较低层的值。这意味着你的自定义配置文件只需写变更的字段,不必复制整份默认配置。
3.2 文件修改(生产常用)
# 查看默认配置目录结构
ls -la /opt/wildduck/config/
# 输出示例:
# default.toml # 主配置,@include 其他文件
# dbs.toml # MongoDB + Redis
# imap.toml # IMAP 协议
# pop3.toml # POP3 协议
# api.toml # HTTP API
# tls.toml # TLS 证书
# dkim.toml # DKIM 签名
# acme.toml # Let's Encrypt
# sender.toml # 外发提交
# attachments.toml # 附件存储
# plugins.toml # 插件
# 创建自定义覆盖配置(推荐方式,不直接改默认文件)
sudo vim /etc/wildduck.toml
# 修改 systemd unit 指定自定义配置文件
sudo systemctl edit wildduck
# 在 [Service] 区块追加:
# ExecStart=
# ExecStart=/usr/bin/node /opt/wildduck/server.js --config=/etc/wildduck.toml
# 重启生效
sudo systemctl restart wildduck
3.3 环境变量覆盖(Docker 场景)
# 环境变量命名规则:APPCONF_ + section 名 + _ + key 名
# 嵌套 section 用下划线连接
# 示例:修改 MongoDB 连接串
APPCONF_dbs_mongo="mongodb://user:pass@mongo-cluster:27017/wildduck"
# 示例:修改 IMAP 对外主机名
APPCONF_imap_setup_hostname="mail.example.com"
# 示例:修改 WebAuthn rpId
APPCONF_webauthn_rpId="example.com"
# 所有 APPCONF_ 环境变量都会进入合并体系,优先级最高
3.4 运行时 API 修改(无需重启)
部分配置项支持运行时修改(通过 API 或 Settings 页面):
# 先获取管理员 token
curl -X POST http://127.0.0.1:8080/authenticate \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"q1w2e3r4","token":true}'
# 列出当前所有配置值
curl -H "X-Access-Token: YOUR_TOKEN" http://127.0.0.1:8080/settings
# 修改单个配置项
curl -X PUT -H "X-Access-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value":"warn"}' \
http://127.0.0.1:8080/settings/log.level
# 当前支持运行时修改的项:
# - log.level(日志级别)
# - webhooks.enabled(Webhooks 开关)
# - tasks.enabled(后台任务开关)
# - emailDomain(默认邮件域名)
⚠️ 注意:通过
PUT /settings/:key修改的值会持久化到 MongoDB 的 settings 集合,优先级高于 TOML 文件和环境变量。如需恢复到文件配置的值,必须先在 API 中删除该 key。
四、参数总览
4.1 配置文件分工
| 文件 | 配置节 | 核心内容 |
|---|---|---|
default.toml | 主配置引用 | ident、processes、默认数据库路径、@include 其他文件 |
dbs.toml | [dbs] | MongoDB、Redis 连接串;可选 [dbs.gridfs] 附件分离库 |
imap.toml | [imap] + [imap.setup] | IMAP 端口、TLS 模式、并发数、消息大小限制 |
pop3.toml | [pop3] + [pop3.setup] | POP3 端口、TLS 模式、最大消息数 |
api.toml | [api] + [api.accessControl] | HTTP API 端口、绑定地址、认证令牌 |
tls.toml | [certs] | TLS 证书路径和密码加密 |
dkim.toml | [dkim] | DKIM 签名开关和默认选择器 |
acme.toml | [acme] | Let's Encrypt 自动证书配置 |
sender.toml | [smtp.setup] | SMTP 对外主机名、端口、TLS 模式 |
attachments.toml | [attachments] | 附件存储后端(MongoDB GridFS / S3) |
plugins.toml | [plugins] | 插件系统开关和插件参数 |
五、核心参数分类详解
5.1 进程与身份(default.toml)
# 进程标题(ps 显示)
ident = "wildduck"
# 工作进程数:数字或 "cpus" 自动匹配 CPU 核数
# 生产建议设为 CPU 核数 × 2,但单进程内存约 300-500MB
processes = 4
# 降权运行:以非 root 用户启动(生产强烈建议)
# user = "wildduck"
# group = "wildduck"
# Node.js 内置调试端口
debugPort = 9229
# 日志级别:silly | verbose | info | warn | error
# 生产推荐 warn,info 排障时临时开启
# silly 会输出每一条 IMAP 命令,极耗 IO
[log]
level = "info"
skipFetchLog = false # true 时跳过 FETCH 响应日志,生产建议 true
5.2 数据库连接(dbs.toml)
[dbs]
# MongoDB 主连接串(必填)
# 格式:mongodb://[user:pass@]host:port[/database][?options]
# 生产集群需指定副本集:mongodb://mongo1:27017,mongo2:27017,mongo3:27017/wildduck?replicaSet=rs0
mongo = "mongodb://127.0.0.1:27017/wildduck"
# Redis 连接串(必填)
# 格式:redis://[user:pass@]host:port[/dbnum]
# dbnum 建议固定用 3,避免与其他应用冲突
redis = "redis://127.0.0.1:6379/3"
# 附件分离存储(可选,推荐磁盘 IO 分离)
# 单独 MongoDB 实例或副本集存储附件,主库存邮件元数据
# [dbs.gridfs]
# mongo = "mongodb://127.0.0.1:27018/attachments"
# disable = false # true 时禁用附件分离
5.3 IMAP 协议参数(imap.toml)
[imap]
# 启用开关:false 时 IMAP 服务不启动(纯 POP3/API 场景)
enabled = true
# 监听端口:993 生产隐式 TLS | 143 STARTTLS | 110 纯文本(禁止)
port = 993
# 绑定地址:0.0.0.0 监听所有网卡 | 127.0.0.1 仅本地 | :: IPv6
host = "0.0.0.0"
# TLS 模式:true 隐式 TLS(连接即加密) | false STARTTLS(升级加密)
# 生产 993 端口必须 true;143 端口必须 false
secure = true
# 单 APPEND 最大消息体(MB)
# 用户通过 IMAP 上传邮件的大小上限
# 建议 25-50,过大附件应走 API upload
maxMB = 25
# 邮件自动清理(天)
# Trash 和 Junk 文件夹内超过此天数的邮件自动删除
# 0 禁用自动清理
retention = 30
# 每用户最大并发 IMAP 连接数
# 默认 15,Webmail 多标签场景可提高到 50
maxConnections = 15
# 启用 COMPRESS=DEFLATE 扩展
# 带宽有限时启用可显著降低传输体积
enableCompression = false
# 期望 HAProxy PROXY protocol v1 头
# 部署在 HAProxy 或 AWS ELB 后启用,获取真实客户端 IP
useProxy = false
[imap.setup]
# 对外主机名(客户端自动配置用到)
# 必须是公网可解析的 FQDN
hostname = "mail.example.com"
# 对外 TLS 模式告知客户端
secure = true
5.4 POP3 协议参数(pop3.toml)
[pop3]
enabled = true
port = 995 # POP3S 隐式 TLS;110 STARTTLS
host = "0.0.0.0"
secure = true
# POP3 LIST/UIDL 最大返回消息数
# 用户邮箱超过此数时需分批拉取
maxMessages = 250
[pop3.setup]
hostname = "mail.example.com"
secure = true
5.5 HTTP API 参数(api.toml)
[api]
enabled = true
port = 8080
# 绑定地址:默认 127.0.0.1 仅本地访问(安全!)
# 部署在反代(Nginx/Traefik)后保持默认
host = "127.0.0.1"
# 启用 HTTPS(直接暴露 API 时启用)
# 建议通过反代做 TLS 终结,此处保持 false
secure = false
[api.accessControl]
# API 访问控制开关
# false = 首用户可未认证创建(部署引导时)
# true = 所有 API 调用需 X-Access-Token
enabled = true
# HMAC 令牌签名密钥(启用 accessControl 时必填)
# 必须与部署脚本/环境变量保持一致
secret = "请替换为长随机串"
# 令牌有效期(秒),使用后自动续期
# 默认 14 天,高安全场景可设 86400(1 天)
tokenTTL = 1209600
5.6 TLS 证书与安全参数
# TLS 证书路径(tls.toml)
[certs]
# 证书私钥加密密钥(可选,增强私钥落盘安全)
# 启用后私钥文件会被 AES-256-GCM 加密存储
# secret = "请替换为随机串"
# 默认证书路径(手动证书模式)
# certFile = "/etc/wildduck/certs/server.crt"
# keyFile = "/etc/wildduck/certs/server.key"
# DKIM 签名(dkim.toml)
[dkim]
# 自动对所有外发邮件进行 DKIM 签名
sign = true
# 默认 DKIM 选择器(DNS 记录用 default._domainkey.example.com)
selector = "default"
# 生产建议每域独立配置选择器和密钥
# [dkim.domains."example.com"]
# selector = "2026q4"
# ACME Let's Encrypt(acme.toml)
[acme]
enabled = true
# 签发邮箱(证书过期通知)
email = "admin@example.com"
# 自动续期阈值(天)
renewDays = 30
# TOTP 二次验证(全局)
[totp]
# 加密 TOTP 密钥落盘
secret = "请替换为随机串"
# WebAuthn/FIDO2(webauthn 节)
[webauthn]
# 依赖方 ID(必须与证书 CN/ SAN 匹配)
rpId = "example.com"
rpName = "WildDuck Mail Server"
challengeSize = 64
attestation = "none"
authenticatorUserVerification = "discouraged"
# 密码泄露检测(pwned 节)
[pwned]
enabled = false # 默认关闭,生产建议开启
type = "softfail" # hardfail 强制拒绝 | fail 拒绝并提示 | softfail 警告但允许 | none 不检查
5.7 外发邮件与附件存储
# SMTP 外发(sender.toml)
[smtp.setup]
# 对外 SMTP 主机名(用于 HELO 和 PTR 解析)
hostname = "mail.example.com"
secure = false # STARTTLS 模式;true 为隐式 TLS(SMTPS)
port = 587
# 附件存储(attachments.toml)
[attachments]
# 存储后端:gridfs(MongoDB 默认)| s3(S3 兼容对象存储)
backend = "gridfs"
# S3 模式配置(可选)
# [attachments.s3]
# bucket = "wildduck-attachments"
# region = "us-east-1"
# accessKey = "..."
# secretKey = "..."
# endpoint = "https://s3.amazonaws.com"
5.8 事件推送与插件
# Webhooks 实时推送(webhooks 节)
[webhooks]
enabled = true # 至少一个 WildDuck 实例需要启用
# 推送事件列表可通过 Settings API 配置
# 默认推送:new_message、authentication、account_change
# 后台任务处理(tasks 节)
[tasks]
enabled = true
# 清理过期 TOTP seed、归档旧日志、重新计算配额等
# 插件系统(plugins.toml)
[plugins]
# 示例:自定义过滤器插件
# [plugins.filters]
# path = "/opt/wildduck/plugins/blocklist.js"
# enabled = true
六、生产配置模板
6.1 单节点生产配置(8GB 内存、500GB SSD、≤500 邮箱)
# /etc/wildduck.toml(仅写变更项,与默认配置合并)
ident = "wildduck-mail-01"
processes = 2 # CPU 4 核时
# user = "wildduck" # systemd 已降权
[dbs]
mongo = "mongodb://127.0.0.1:27017/wildduck"
redis = "redis://127.0.0.1:6379/3"
[imap]
port = 993
host = "0.0.0.0"
secure = true
maxMB = 25
retention = 30
maxConnections = 30
enableCompression = true
[imap.setup]
hostname = "mail.example.com"
[pop3]
port = 995
secure = true
maxMessages = 500
[pop3.setup]
hostname = "mail.example.com"
[api]
host = "127.0.0.1" # 反代后保持本地绑定
port = 8080
[api.accessControl]
enabled = true
secret = "6f3a8b5c4d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a"
tokenTTL = 86400
[tls]
# 使用 Traefik 或 ACME 自动证书
# certFile = "/etc/letsencrypt/live/example.com/fullchain.pem"
# keyFile = "/etc/letsencrypt/live/example.com/privkey.pem"
[dkim]
sign = true
selector = "default"
[acme]
enabled = true
email = "admin@example.com"
renewDays = 30
[totp]
secret = "a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2"
[webauthn]
rpId = "example.com"
rpName = "Example Mail"
[pwned]
enabled = true
type = "softfail"
[log]
level = "warn"
skipFetchLog = true
[webhooks]
enabled = true
[tasks]
enabled = true
6.2 Docker Compose 环境变量模板(节选)
# docker-compose.yml environment 段
environment:
- APPCONF_dbs_mongo=mongodb://mongo:27017/wildduck
- APPCONF_dbs_redis=redis://redis:6379/3
- APPCONF_imap_port=993
- APPCONF_imap_host=0.0.0.0
- APPCONF_imap_secure=true
- APPCONF_imap_setup_hostname=mail.example.com
- APPCONF_imap_enableCompression=true
- APPCONF_pop3_port=995
- APPCONF_pop3_secure=true
- APPCONF_api_host=127.0.0.1
- APPCONF_api_port=8080
- APPCONF_api_accessControl_enabled=true
- APPCONF_pwned_enabled=true
- APPCONF_pwned_type=softfail
- APPCONF_log_level=warn
- APPCONF_log_skipFetchLog=true
七、常见问题
Q1:修改配置后需要重启服务吗?
大部分参数(IMAP/POP3 端口、TLS 模式、进程数、数据库连接等)修改后必须重启。只有以下参数支持运行时修改:
log.level(日志级别)webhooks.enabledtasks.enabledemailDomain- DKIM 选择器配置
Q2:SIGHUP 信号能重载配置吗?
不能。WildDuck 收到 SIGHUP 信号生成 heap snapshot(用于 Node.js 堆内存调优),不重载配置。修改配置后只能 systemctl restart wildduck 重新加载。
Q3:如何给 WildDuck 配置高可用 Redis(Sentinel)?
[dbs]
# Redis Sentinel 连接串格式
redis = "redis://user:pass@sentinel1:26379,sentinel2:26379,sentinel3:26379/3?sentinelName=redis-rs"
# APPCONF 形式:
# APPCONF_dbs_redis="redis://sentinel1:26379,sentinel2:26379,sentinel3:26379/3?sentinelName=redis-rs"
Q4:OpenSearch 全文搜索如何开启?
# 追加到自定义配置文件末尾
[elasticsearch]
enabled = true
# 连接串
host = "https://opensearch:9200"
# 索引名
index = "wildduck-messages"
# 同步间隔(秒)
syncInterval = 300
# 批量索引大小
bulkSize = 500
Q5:附件分离到独立 MongoDB 实例的好处?
- 磁盘 IO 隔离:附件读写不阻塞邮件元数据的高并发查询
- 独立扩容:附件存储通常比元数据增长快 5-10 倍,可单独分片扩容
- 备份策略分离:附件备份频率低、增量压缩率高,元数据需更频繁的 point-in-time 备份
八、参考链接
- WildDuck 官方配置文档:https://docs.wildduck.email/docs/operations/configuration/
- wild-config 项目仓库:https://github.com/zone-eu/wild-config
- 源码默认配置:https://github.com/zone-eu/wildduck/blob/master/config/default.toml
- 运行时 Settings API:https://docs.wildduck.email/api/#operation/getSettings
- 附件存储指南:https://docs.wildduck.email/docs/operations/attachment-storage
- OpenSearch 全文搜索:https://docs.wildduck.email/docs/concepts/full-text-search