它是什么
我在香港 VPS 上用 docker-mailserver 搭了 xiejun-server.top 的自有域名邮箱,同时手上还留着 126 和 yeah.net 两个老账号。手机装一套客户端、公司电脑再装一套,账号一多就顾不过来。于是我干脆在 VPS 上放了一个 SnappyMail 网页邮箱:打开一个地址,就能同时收发这三个邮箱。
SnappyMail 本质上还是一个标准的 IMAP/SMTP 客户端,只是把界面搬到了浏览器里。它真正的难点与收信无关,全在兼容性上:126 / yeah.net 登录时会校验 IMAP 的 ID 命令,原生客户端不发这条命令就会直接报“Unsafe Login”拒登,所以我给 ImapClient.php 打了补丁,在握手阶段补上 ID 信息。外面用 Caddy 做反向代理并自动签发 Let's Encrypt 证书,进出都是 HTTPS。
现在状态
运行中。自建域名的收信走 Dovecot 的 993 端口,发信经 Brevo 中继出网,因为腾讯云 VPS 的出站 25 被封;126、yeah.net 用授权码直连。手机和电脑浏览器都能用,不必再折腾客户端配置。
功能
- 一个网页入口同时管理自建域名邮箱、126、yeah.net 三个账号
- 给 SnappyMail 的 IMAP 客户端打补丁,登录时发送 ID 命令,解决网易邮箱“Unsafe Login”拒登
- Caddy 反向代理 + 自动 HTTPS,证书由 Let's Encrypt 签发
- 后端直接复用 docker-mailserver 的 IMAP 993 / SMTP 465·587,不改邮箱服务本身
- 响应式界面,手机与电脑浏览器都能用,无需安装 App
技术栈
使用 / 部署教程
部署步骤
1. 前置准备
先给域名加一条 A 记录,例如 webmail.example.com 指向你的 VPS 公网 IP,并确认 80/443 端口可达,因为 Caddy 要用 HTTP-01 申请证书。同时准备好已有的邮箱账号:自建域名邮箱的 IMAP 地址与密码,网易系账号的客户端授权码。
2. 起容器
按 compose.yaml 起一个 SnappyMail 容器,Web 端口只在 Docker 内网暴露,不直接映射到宿主机公网。需要改的通常只有数据卷路径和时区。
3. 反向代理与 HTTPS
在 Caddyfile 里加一段:
webmail.example.com {
reverse_proxy snappymail:8888
encode zstd gzip
}
caddy reload 之后 Caddy 会自动申请并续期证书,浏览器访问应该直接是 HTTPS。
4. 打 IMAP ID 补丁
把 patches/ImapClient.php 覆盖到容器内对应的 ImapClient.php。更稳的做法是在构建镜像时 COPY 进去,避免容器重建后补丁丢失;只 docker cp 覆盖一次,重建后就没了。
5. 配置邮箱账号
打开 https://webmail.example.com/?admin,用初始管理员账号登录后第一件事是改密码。然后在 Domains 里为每个邮箱配置:
- 自建域名:IMAP
mail.xiejun-server.top:993 SSL/TLS,SMTPmail.xiejun-server.top:465 SSL/TLS(或 587 STARTTLS),用户名填完整邮箱地址。 - 126 / yeah.net:服务器地址与端口按服务商说明填写(一般是 993 / 465 走 SSL),密码要填邮箱网页端生成的客户端授权码,不是登录密码。
6. 验证
用普通登录页登录各个账号,确认收件箱能正常加载、邮件能发出;再从外部邮箱回一封,确认收发两端都正常。
注意
- 一定要用 HTTPS,不要在明文 HTTP 下传输邮箱密码。
- 管理员面板不要长期用默认凭据,也不要对公网无限制开放。
注意
- 邮箱密码与授权码不要写进仓库里的 compose.yaml 或 Caddyfile,用环境变量或本地未提交的 env 文件。
- 126 / yeah.net 必须使用客户端授权码;直接填网页登录密码会被拒。
- SnappyMail 升级会覆盖 ImapClient.php,升级后需重新打补丁并回归测试网易账号登录。