docker-mailserver 日常运维手册
docker-mailserver 日常运维手册:队列/日志/磁盘巡检实测、收发链路排障(发信-队列-日志追踪)、账号/别名/配额管理、升级与备份迁移,全部命令附真实回显。
docker-mailserver 日常运维手册
> 目标:覆盖 docker-mailserver(DMS)上线后的日常运维闭环——队列/日志/磁盘巡检、收发链路排障(发信 → 投递文件 → 日志追踪)、账号/别名/配额管理、升级与备份迁移。全部命令与回显在 Ubuntu 22.04 + DMS 16.0.1 实测,数据目录 /opt/data/docker-mailserver/,邮件主机名 mail.example.com,日志文件 /var/log/mail/mail.log。
一、环境信息
- 操作系统:Ubuntu 22.04;docker-mailserver:16.0.1(Postfix 3.10.13 / Dovecot 2.4.1-4 / Rspamd 4.1.5 / ClamAV 1.4.3 实测版本)
- 服务监听:25(SMTP)、587(认证提交)、143(IMAP)、993(IMAPS,TLS 启用后)
- 数据目录:
/opt/data/docker-mailserver/(mail-data/邮件、state/状态、config/配置、logs/日志) - 已建账号:
admin@example.com、user@example.com(密码q1w2e3r4);别名info@example.com → admin@example.com - 管理入口:
/opt/data/docker-mailserver/setup.sh;原生命令(postqueue/doveadm/rspamc/fail2ban-client)均可用 - 测试工具:swaks 3.0(SMTP 全能测试器,Ubuntu 包管理器
apt install swaks安装)
二、日常巡检
巡检目的是在用户报障前发现队列积压、磁盘水位、认证异常三类问题。以下五组命令构成每巡检一次的完整闭环。
2.1 队列巡检
队列是最先出问题的位置(对端拒收、目标域宕机都会积压在这里):
postqueue -p
正常态实测回显(队列为空):
Mail queue is empty
有积压时的回显形态(实测一次发往不可达地址的积压):
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
08381900977 281 Sun Oct 18 08:52:20 admin@example.com
(connect to mail.dead.test[10.255.255.1]:25: Connection refused)
nobody@dead.test
-- 0 Kbytes in 1 Request.
巡检要点:关注积压条数与括号内失败原因;
Connection refused/Connection timed out属对端问题可等待自动重试,Relay access denied属配置问题需立即处理(见 7.1)。
2.2 日志巡检
日志文件为 /var/log/mail/mail.log(已挂载持久化到数据目录)。用收发状态计数做量化巡检(实测回显):
grep -c 'status=sent' /var/log/mail/mail.log # 投递成功数
grep -c 'status=deferred' /var/log/mail/mail.log # 延迟数
grep -c 'rejected' /var/log/mail/mail.log # 拒绝数(含反垃圾/中继/伪造)
8
2
8
巡检要点:
deferred持续增长看 2.1 的队列原因;rejected增长结合 7.3/7.4 的反垃圾与中继排查;同时抽查认证失败行grep 'SASL LOGIN authentication failed' /var/log/mail/mail.log判断是否有人爆破(触发封禁的实测见《docker-mailserver 安全加固指南》)。
2.3 磁盘巡检
df -h /opt/data | tail -1
du -sh /opt/data/docker-mailserver/mail-data /opt/data/docker-mailserver/state /opt/data/docker-mailserver/config /opt/data/docker-mailserver/logs
实测回显:
/dev/sda3 786G 206G 546G 28% /
192K /opt/data/docker-mailserver/mail-data
112M /opt/data/docker-mailserver/state
56K /opt/data/docker-mailserver/config
404K /opt/data/docker-mailserver/logs
巡检要点:
state/是体积大头(其中 ClamAV 病毒库随更新增长,实测 112M 中占绝对多数),属正常;mail-data/随邮件量线性增长,低于 20% 剩余水位需扩容或促用户清理。
2.4 服务健康巡检
认证链路可用性一分钟验证(实测回显):
doveadm auth test admin@example.com q1w2e3r4
passdb: admin@example.com auth succeeded
extra fields:
user=admin@example.com
反垃圾引擎在线验证(实测回显):
rspamc -h 127.0.0.1:11334 counters
Results for symbol scoring: 1/1
Performances: 0.000084 sec
...
封禁系统巡检(实测回显,三 jail 常驻):
fail2ban-client status
Status
|- Number of jail: 3
`- Jail list: custom, dovecot, postfix
2.5 邮箱容量巡检
./setup.sh email list
实测回显(含配额使用率与别名标注):
* admin@example.com ( 8.0K / ~ ) [0%]
[ aliases -> info@example.com ]
* user@example.com ( 5.0K / 1.0G ) [0%]
三、备份与恢复
3.1 备份内容与方式
备份对象为数据目录全集(邮件 + 状态 + 配置 + 日志 + 证书 + 管理文件)。推荐离线备份(先停服再打包,保证一致性);在线备份亦可做,但需接受套接字文件被跳过的提示(3.3)。
tar -czf /tmp/dms-backup-2026-10-18.tar.gz \
mail-data state config logs ssl mailserver.env docker-compose.yml setup.sh
实测回显(在线备份,套接字提示属正常):
tar: state/lib-rspamd/rspamd.sock: socket ignored
tar: state/spool-postfix/private/rewrite: socket ignored
tar: state/spool-postfix/private/lmtp: socket ignored
tar: state/spool-postfix/private/defer: socket ignored
...(spool-postfix 下各服务套接字同样提示,略)
110M /tmp/dms-backup-2026-10-18.tar.gz
实测包体 110M(主体为 ClamAV 病毒库;邮件量增长后包体随之增长)。
3.2 恢复流程
目标机按《docker-mailserver Docker Compose 部署指南》完成前置(DNS、目录),然后反向恢复:
- 解包覆盖数据目录:
tar -xzf dms-backup-2026-10-18.tar.gz -C /opt/data/docker-mailserver/; docker compose up -d --force-recreate重建实例(账号/别名/配额/DKIM 密钥均在config/内自动装载);- 验证三件套:
./setup.sh email list(账号与配额)、doveadm auth test admin@example.com q1w2e3r4(认证)、发一封测试信追踪status=sent。
3.3 注意事项
postfix-accounts.cf存的是口令哈希,备份包请按敏感数据管理;- 在线备份的
socket ignored提示不影响数据文件完整性,但队列 spool 可能含瞬态条目,严格一致还原请在停服窗口做; - 跨大版本升级后的恢复请优先用同版本备份(版本兼容说明见官方 Release Notes)。
四、监控告警
无外部监控栈时,把 2.1~2.3 的巡检命令脚本化即可搭建最低可用告警面。建议的三个告警触发点(阈值可按团队调整):
| 检查点 | 命令 | 建议告警条件(实测基准) |
|---|---|---|
| 队列深度 | postqueue -p 统计队列条目数 | > 50 条持续 15 分钟 |
| 磁盘水位 | df -h /opt/data 取使用率列 | 使用率 > 80%(实测基线 28%) |
| 投递异常 | grep -c 'status=deferred' /var/log/mail/mail.log | 相对前日同时段增量 > 100 |
邮件状态行(status=sent/deferred/rejected)与队列原因括号文本是日志侧的原始告警源;垃圾分拣事件可在信头查 X-Spam: Yes(实测触发见 7.3)。fail2ban 的封禁历史落库于 state/lib-fail2ban/fail2ban.sqlite3(实测文件 73728 字节),可用 sqlite3 查询历史封禁做安全告警。
五、扩容缩容
- 磁盘扩容:邮件/日志/状态全在
/opt/data/docker-mailserver/,扩容块设备或挂新盘迁移目录后重建实例即可;巡检基线见 2.3。 - 配额扩容/缩容:
./setup.sh quota set user@example.com 2G覆盖旧值(实测由 1G 改配后email list立即显示新值),./setup.sh quota del user@example.com恢复不限额(实测回显~)。 - 域名扩容:
./setup.sh email add <用户@新域名> <密码>创建首个新域账号时自动登记新邮件域(首域example.com即此机制实测登记),随后为新域发布 MX/SPF/DKIM/DMARC 记录(DKIM 需对新域再执行./setup.sh config dkim)。 - 账号缩容:删除账号见 7.5(含数据一并清除的交互确认)。
六、升级与回滚
6.1 升级流程
升级 = 换镜像标签 + 重建实例,数据与配置全部保留在挂载目录(实测过同机制重建,主配置覆盖随重建生效):
- 小版本升级(如 16.0.x):
docker compose中把image:改为新版本标签 →docker compose up -d --force-recreate; - 大版本升级(如 15.x → 16.x):先读官方 Release Notes 中的破坏性变更(本批实测经验:v16 推荐 Rspamd 单栈,旧栈四项 env 建议同步置 0),再执行升级;
- 升级后验证:启动日志版本自报(
Welcome to docker-mailserver v16.0.1)→docker compose ps状态healthy→ 2.4 的认证/反垃圾巡检全通过 → 发一封测试信。
6.2 回滚流程
把 image: 改回旧版本标签 → up -d --force-recreate。注意配置向下兼容:回滚前确认新版本期间未引入旧版不支持的覆盖配置(config/ 下新增文件可先移出),账号数据文件格式跨补丁版本兼容。
七、故障排查手册
7.1 队列管理三板斧(hold/release/delete)
对 2.1 中积压的邮件按 Queue ID 操作(实测全程):
postsuper -h 08381900977 # 暂缓(hold,便于保住现场)
postsuper: 08381900977: placed on hold
postsuper: Placed on hold: 1 message
hold 后队列条目带 ! 标记(实测:08381900977!)。放行与强制刷新:
postsuper -H 08381900977 # 释放回队列
postqueue -f # 立即刷新重试
postsuper: 08381900977: released from hold
postsuper: Released from hold: 1 message
删除队列条目:
postsuper -d 08381900977
postqueue -p
postsuper: 08381900977: removed
postsuper: Deleted: 1 message
Mail queue is empty
7.2 收发链路排障标准动线
排障动线:发信测试 → 定位投递文件 → 日志追踪,三步全部实测。
第一步:发信测试(认证提交链路)。从测试机经 587 端口认证发一封信(swaks 实测关键回显):
<- 220 mail.example.com ESMTP
<- 250-STARTTLS
<- 220 2.0.0 Ready to start TLS
=== TLS started with cipher TLSv1.3:TLS_AES_256_GCM_SHA384:256
第二步:定位投递文件。信件以 Maildir 单文件形式落在收件人目录(实测路径形态):
/opt/data/docker-mailserver/mail-data/example.com/user/new/1792284609.M194758P1079.mail.example.com,S=1049,W=1075
第三步:日志追踪(按 Queue ID 串联全链路)。发信回显拿到 250 2.0.0 Ok: queued as BDE429008EF 后按 ID 检索:
grep 'BDE429008EF' /var/log/mail/mail.log
实测回显(本地投递,经 LMTP 完成):
2026-10-18T08:59:43.724810+08:00 mail postfix/lmtp[2442]: D91AA9005FF: to=<admin@example.com>, orig_to=<info@example.com>, relay=mail.example.com[/var/run/dovecot/lmtp], delay=0.87, ..., status=sent (250 2.0.0 <admin@example.com> eIbZKv8Z1GqLCQAAYIgGOA Saved)
失败信的关键字段同位:status=deferred (connect to ...: Connection refused)(实测见 2.1)、dsn=4.4.1 等增强状态码直接给出失败类别。
7.3 垃圾误判排查
入站信被分拣到 Junk 的实测链路:信头 X-Spam: Yes + X-Spamd-Result 评分明细 + 落点目录 mail-data/example.com/admin/.Junk/new/。实测一封冒名 gmail 的信:spf=softfail、dmarc=fail (policy=none),评分 10.00 → 改投 Junk。处理手段:调阈值(config/rspamd/override.d/actions.conf)、按信头符号明细豁免(Rspamd 官方 multimap 模块)。
7.4 中继与收发域问题
- 外部来源投递非本域收件人被拒(实测):
554 5.7.1 <nobody@dead.test>: Relay access denied——防开放中继的正确行为,合法出站走 587 认证提交; - 发件域不可解析被拒(实测):
450 4.1.8 <friend@external.test>: Sender address rejected: Domain not found——reject_unknown_sender_domain默认行为,测试时用真实域名; - 本域伪造入站被 milter 拒信(实测):
554 5.7.1 Spam message rejected(DMARC p=quarantine 生效),处置细节见《docker-mailserver 安全加固指南》。
7.5 账号管理操作全集
创建与列表(实测:email add 静默成功、退出码 0;列表回显见 2.5)。删除账号实测——email del 有交互确认:
./setup.sh email del third@example.com
Do you want to delete the mailbox data as well (removing all mails)? [y/N]
确认后(实测回显):
INFO delmailuser: Deleting mailbox data: '/var/mail/example.com/third'
INFO delmailuser: 'third@example.com' and associated data (aliases, quotas) deleted
别名增删查(实测):./setup.sh alias add info@example.com admin@example.com 写入 config/postfix-virtual.cf(实测内容 info@example.com admin@example.com),投递改写证据见《docker-mailserver Docker Compose 部署指南》4.5。配额管理见第五章。改密用 ./setup.sh email update <地址> <新密码>。
7.6 认证问题排查
登录失败先用 doveadm auth test 验证口令与账号存在性(成功回显见 2.4);连续失败会触发 fail2ban 封禁(来源地址被防火墙丢弃、连接挂起),用 ./setup.sh fail2ban 查看封禁列表(实测回显 Banned in postfix: 100.64.0.20)、./setup.sh fail2ban unban <IP> 解封(实测回显 Unbanned IP from postfix: 1),完整封禁/解封实测见《docker-mailserver 安全加固指南》。
八、常见问题
Q1:tar 备份时报一堆 socket ignored?
见 3.1/3.3:state/spool-postfix/ 与 state/lib-rspamd/ 下的套接字是运行时 IPC 点,不属数据,跳过即正常。要绝对一致请在停服窗口打包。
Q2:email del 卡住不动?
它有 [y/N] 交互确认(实测见 7.5),在脚本/管道环境需显式应答 y 才会继续执行删除。
Q3:日志里来源主机名显示异常长的一串?
日志形如 from=<主机名>[<IP>] 的主机名取决于该 IP 的反解(PTR)。本实验环境为测试机配置了正向/反向记录(client.external.test ↔ 100.64.0.20),反解生效后日志即显示该主机名。生产中若显示大写连串名,多为反解缺失,按 IP 过滤日志即可。
Q4:升级后 state/ 里出现已禁用组件的目录(如 lib-amavis)?
目录在首次初始化时创建、保留不删除;组件是否运行以 ps aux 与启动日志为准(本实测环境 Amavis 已禁用但目录仍在,属正常)。
Q5:postqueue -p 看到的失败原因哪类需要人工介入?
Connection refused/timed out(对端不可达)等待自动重试即可;Relay access denied、Domain not found 属配置/输入问题,按 7.4 处理;Spam message rejected 是反垃圾判定,按 7.3 复核评分明细。
九、参考链接
- 官方 FAQ(运维向):
https://docker-mailserver.github.io/docker-mailserver/latest/faq/ - Postfix 队列管理手册:
https://www.postfix.org/postqueue.1.html、https://www.postfix.org/postsuper.1.html - Dovecot 管理工具:
https://doc.dovecot.org/admin-manual/ - Rspamd 命令行:
https://www.rspamd.com/doc/ - fail2ban 客户端:
https://fail2ban.readthedocs.io/