Stalwart + SnappyMail Docker 部署踩坑记录

环境

  • 邮件服务器: Stalwart Mail Server (Docker)
  • Web 邮件客户端: SnappyMail (Docker)
  • 反向代理: Cloudflare (仅代理 HTTP/HTTPS)

问题:SnappyMail 无法登录

错误信息

1
AUTHENTICATIONFAILED Authentication failed

排查过程

1. 误以为是 SSL/TLS 问题

  • 尝试使用 SSL/TLS 端口 (993),报错 Can't connect to host
  • 尝试使用 STARTTLS,报错 Cannot enable STARTTLS
  • 结论: 不是加密问题

2. 误以为需要允许明文认证

在 Stalwart 配置中添加:

1
2
[imap.auth]
allow-plain-text = true

实际上不需要,因为 SnappyMail 会自动使用 STARTTLS 升级加密。

3. 真正的问题:Login name ≠ Email

在 Stalwart 中,Login nameEmail 是两个不同的字段:

字段 用途
Login name test IMAP/SMTP 认证用的用户名
Email test@example.com 邮箱地址

我一直用 test@example.com 登录,但实际的 Login name 是 test

解决方案

方案 A: 在 SnappyMail Domain 配置中勾选 “使用短用户名登录”

  • 会自动将 user@domain.com 转换为 user

方案 B: 在 Stalwart 中把 Login name 改成完整邮箱地址

  • 将 Login name 从 test 改为 test@example.com

关键知识点

  1. Cloudflare 只能代理 HTTP/HTTPS,IMAP (143/993) 和 SMTP (25/465/587) 无法通过 Cloudflare 代理

  2. 容器间通信使用 Docker 内部网络,配置时使用容器名(如 stalwart-mail)而不是域名

  3. SnappyMail 会自动协商加密,即使选择"无加密",也会尝试使用 STARTTLS

  4. Stalwart 的 Login name 和 Email 是分开的,这是很多邮件系统的设计,但容易混淆

调试命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 测试容器间网络连通性
docker exec -it snappymail-web sh -c "ping -c 3 stalwart-mail"

# 测试 IMAP 端口
docker exec -it snappymail-web sh -c "nc -zv stalwart-mail 143"

# 测试 IMAP 认证(注意用正确的 Login name)
docker exec -it snappymail-web sh -c "
echo -e 'a LOGIN \"username\" \"password\"\na LOGOUT' | nc stalwart-mail 143
"