想用自己的域名收发邮件,又不想分别安装 Postfix、Dovecot、Rspamd、Webmail 和证书服务,Mailcow 是目前较完整的自托管邮件套件之一。它把 SMTP、IMAP、SOGo Webmail、反垃圾、病毒扫描、DKIM 和管理后台组合在一套 Docker Compose 项目中。
但邮件服务器不是“容器启动就能用”。VPS 的 25 端口、独立公网 IP、PTR 反向解析和 IP 历史信誉,往往比 CPU 性能更重要。机器选错后,即使后台全绿,发往 Gmail、Outlook 或企业邮箱的邮件仍可能被拒收或进入垃圾箱。
这篇教程从购买 VPS 前的检查开始,使用 Mailcow 官方 mailcow-dockerized 仓库完成安装,配置 A、MX、PTR、SPF、DKIM、DMARC、TLS、反垃圾、备份和升级,并给出送达率与常见故障排查清单。
Mailcow 是完整的邮件和协作套件,不是轻量 SMTP 转发器。
| 需求 | 是否适合 Mailcow | 原因 |
|---|---|---|
| 小团队使用自有域名邮箱、日历和通讯录 | 适合 | 包含 SOGo、IMAP、SMTP、ActiveSync 相关能力和统一后台 |
| 需要控制邮箱数据、归档和账号生命周期 | 适合 | 数据保存在自己的 VPS 与 Docker Volumes 中 |
| 网站只需发送验证码、通知邮件 | 通常不适合 | 专业事务邮件服务更省运维,也更容易建立送达信誉 |
| 批量营销邮件、冷邮件 | 不适合 | 容易损害 IP 和域名信誉,也可能违反 VPS 服务条款 |
| 无法获得 PTR 或开放 25 端口的 VPS | 不适合 | 外部邮件服务器可能直接拒收或降低信誉 |
如果只是给 Ghost、WordPress 或业务系统发送通知,不需要员工邮箱,优先考虑 Amazon SES、Postmark、Mailgun 等事务邮件服务。Mailcow 更适合确实需要完整邮箱、Webmail、日历和域名管理的团队。
先阅读供应商的 Acceptable Use Policy,并向客服确认允许自建邮件服务器。部分廉价 VPS 禁止邮件服务,或者默认永久封锁出站 TCP 25。
“可以在安全组开放 25”不代表上游网络允许出站。购买前明确询问:
- 入站 TCP 25 是否开放;
- 出站 TCP 25 是否开放,是否需要提交解封申请;
- 465、587、993、80、443 等端口是否有限制;
- 新账号是否有等待期或 KYC 要求。
如果供应商只能开放 587,仍不能替代服务器之间投递所需的 25 端口。
公网 IPv4 的 PTR 应由 VPS/IP 提供商设置为 Mailcow 主机名,例如:
203.0.113.10 -> mail.example.com
同时 mail.example.com 的 A 记录必须正向解析回同一个 IP。正反向不一致是邮件进入垃圾箱或被拒收的常见原因。
拿到 IP 后先检查常见实时黑名单和历史滥用记录。如果 IP 已有严重垃圾邮件信誉,最省时间的方案通常是让供应商更换 IP,而不是试图用一个新域名慢慢“洗白”。
有关拒收、垃圾箱和鉴权结果的进一步排查,可以配合VPS 自建邮箱送达率排查指南使用。
Mailcow 官方给出的默认配置最低要求是 6GiB 内存加 1GiB Swap,磁盘最低 20GiB且不包含邮件数据;官方建议约 5 至 10 个用户使用 8GiB 内存。ClamAV 和全文搜索会明显占用内存。
| 使用场景 | 建议 VPS 配置 | 说明 |
|---|---|---|
| 个人或 3 个以内邮箱 | 4 核、8GB、80GB SSD | 保留 ClamAV 与全文搜索,并预留系统和备份空间 |
| 5-10 个用户 | 4 核、8-16GB、160GB SSD | 依据附件、保留年限和移动端连接数扩容 |
| 约 50 个并发 IMAP、多个 ActiveSync 设备 | 8 核、16GB 起 | 官方示例建议 16GiB,部署前应做容量评估 |
| 低于 6GB 内存 | 不建议使用默认配置 | 即使关闭 ClamAV/FTS,也会降低功能和安全余量 |
不要只看邮箱账号数量。手机长连接、全文索引、大附件、垃圾邮件训练和备份都会影响资源。还没确定机器规格时,可先参考VPS 配置选择指南。
虚拟化必须使用 KVM、ESX、Hyper-V 等完整虚拟化。Mailcow 官方不支持 OpenVZ、Virtuozzo 和 LXC 容器型 VPS。系统以 Ubuntu 24.04 LTS、x86_64 为例。
本文使用以下示例:
邮件域名:example.com
Mailcow 主机名:mail.example.com
服务器 IPv4:203.0.113.10
主机名必须是完整域名,不能只写 mail,也不应直接使用根域名 example.com。如果 DNS 托管在 Cloudflare,mail.example.com 必须设为 DNS only,不能打开橙云代理,因为 Cloudflare 普通代理不转发 SMTP、IMAP 等邮件端口。
安装前设置服务器主机名与时区:
sudo hostnamectl set-hostname mail.example.com
sudo timedatectl set-timezone Asia/Shanghai
hostname -f
timedatectl status
时间错误会影响 TLS、日志关联和 TOTP 两步验证,不能跳过。
Mailcow 默认会使用这些 TCP 端口:
| 端口 | 用途 |
|---|---|
| 25 | 邮件服务器之间的 SMTP 投递 |
| 465 / 587 | 邮件客户端加密提交 |
| 143 / 993 | IMAP / IMAPS |
| 110 / 995 | POP3 / POP3S |
| 4190 | ManageSieve 过滤规则 |
| 80 / 443 | 管理后台、Webmail、证书验证 |
安装前检查是否已有 Nginx、Apache、Postfix 或其他服务占用端口:
sudo ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'
理想输出为空。Mailcow 自带 Nginx 和证书组件,第一套安装不建议再套 Caddy 或 Nginx Proxy Manager。已有网站占用 80/443 时,应按照 Mailcow 官方反向代理文档调整绑定端口,而不是随手改 Compose 文件。
Mailcow 当前要求 Docker Engine 24.0 或更高版本、Docker Compose 2.0 或更高版本。使用 Docker 官方仓库安装,不要使用多年不更新的发行版旧包。
安装 Mailcow 所需工具:
sudo apt update
sudo apt install -y git openssl curl gawk coreutils grep jq
docker --version
docker compose version
生产环境中的 Docker 日志、磁盘空间和回滚原则,可以参考VPS Docker Compose 生产配置清单。不要直接修改 Mailcow 自动维护的 docker-compose.yml;个性化覆盖应使用官方支持的配置方式。
克隆官方仓库并生成配置:
sudo -i
umask 0022
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh
脚本询问主机名时填写:
mail.example.com
然后检查 /opt/mailcow-dockerized/mailcow.conf 的关键项:
MAILCOW_HOSTNAME=mail.example.com
TZ=Asia/Shanghai
SKIP_LETS_ENCRYPT=n
SKIP_CLAMD=n
SKIP_FTS=n
ENABLE_IPV6=false
只有 VPS 已正确配置公网 IPv6、AAAA 和 IPv6 PTR 时,才把 ENABLE_IPV6 设为 true。没有完整 IPv6 邮件链路却强行启用,可能导致部分投递从未建立信誉的 IPv6 发出。
generate_config.sh 会生成数据库密码等随机配置,不要把 mailcow.conf 上传到公开 Git 仓库。
启动服务:
docker compose pull
docker compose up -d
docker compose ps
Mailcow 包含多个容器,首次拉取和初始化需要几分钟。不要只看某一个容器为 Up,应检查所有核心服务:
docker compose ps
docker compose logs --tail=100 nginx-mailcow
docker compose logs --tail=100 postfix-mailcow
docker compose logs --tail=100 dovecot-mailcow
docker compose logs --tail=100 acme-mailcow
先创建能让服务器上线和收信的记录。不同 DNS 控制台字段名称略有差异:
mail A 203.0.113.10
@ MX 10 mail.example.com.
autodiscover CNAME mail.example.com.
autoconfig CNAME mail.example.com.
@ TXT "v=spf1 mx a -all"
_dmarc TXT "v=DMARC1; p=none; rua=mailto:[email protected]"
同时在 VPS 提供商控制台设置:
PTR 203.0.113.10 -> mail.example.com
先用 p=none 收集 DMARC 报告,确认合法来源都通过 SPF 或 DKIM 对齐后,再逐步改为 quarantine 或 reject。如果域名还通过第三方服务发信,不能照抄 v=spf1 mx a -all,必须把所有合法发送源合并到唯一一条 SPF 记录中。
等待解析生效后检查:
dig +short A mail.example.com
dig +short MX example.com
dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short -x 203.0.113.10
A 与 PTR 必须互相对应,MX 目标必须是主机名而不是 IP。
浏览器打开:
https://mail.example.com/admin
官方初始账号为 admin,默认密码为 moohoo。第一次登录后立即:
- 修改管理员密码;
- 启用两步验证;
- 创建第二个受控管理员作为恢复入口;
- 确认 TLS 证书已签发且浏览器无警告;
- 不允许普通邮箱账号拥有不必要的管理权限。
如果公网已能访问后台但还没修改默认密码,应先限制访问再继续配置。
在 Mailcow 管理后台依次完成:
- Configuration → Mail Setup → Domains,添加
example.com; - 创建
[email protected]、[email protected]等需要的邮箱; - 为域名生成 DKIM Key;
- 把后台显示的完整 DKIM TXT 值复制到 DNS;
- 等待解析后,在后台重新执行 DNS 检查。
DKIM 记录通常类似:
dkim._domainkey TXT "v=DKIM1; k=rsa; p=这里使用后台生成的公钥"
不要手工编造 p= 后的公钥,也不要把私钥放进 DNS。记录过长时,DNS 服务商可能自动拆成多个字符串,只要最终 TXT 查询能拼回完整值即可。
Docker 发布端口会经过转发链。Mailcow 官方明确提醒,单纯写 UFW/INPUT 规则可能无法限制容器端口;需要把限制放到 DOCKER-USER 或外部云防火墙中。
邮件服务器至少要允许真正需要的公网端口。管理后台若只供团队使用,可在上游防火墙限制来源 IP;SMTP 25 和收件人使用的邮件协议端口则不能误封。
应用规则后从另一台机器实际测试,而不是只看本机:
nc -vz mail.example.com 25
nc -vz mail.example.com 443
nc -vz mail.example.com 587
nc -vz mail.example.com 993
openssl s_client -starttls smtp -connect mail.example.com:25 \
-servername mail.example.com </dev/null
云防火墙、宿主机规则和 Docker 链必须一起检查。不要在远程 SSH 会话里批量清空 iptables 规则。
正式迁移域名邮箱前,至少完成四轮测试:
从 Gmail、Outlook 或其他外部邮箱发信到 [email protected],确认能进入 SOGo 与 IMAP 客户端。
分别发送到 Gmail、Outlook 和另一家企业邮箱,检查邮件是否进入收件箱。不要只给同域邮箱互发,那不会经过真实互联网投递链路。
在收件方查看原始邮件头,确认:
spf=pass
dkim=pass
dmarc=pass
三项通过仍不保证进入收件箱,IP 信誉、内容、发送节奏和用户反馈也会影响结果。
cd /opt/mailcow-dockerized
docker compose logs --since=30m postfix-mailcow
docker compose logs --since=30m rspamd-mailcow
docker compose exec postfix-mailcow postqueue -p
遇到 timeout、connection refused、blocked using 或 550 5.7.x 时,保留完整对端响应再处理,不要反复重发制造更多负面信号。
Mailcow 官方提供 helper-scripts/backup_and_restore.sh,可以备份邮件、数据库、加密材料、Redis、Rspamd 和 Postfix 数据。不要把脚本复制到别处,直接在仓库中运行:
sudo mkdir -p /opt/mailcow-backups
cd /opt/mailcow-dockerized
MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups \
./helper-scripts/backup_and_restore.sh backup all --delete-days 7
检查生成的备份目录和日志后,再设置 Cron:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
30 3 * * * cd /opt/mailcow-dockerized && MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups ./helper-scripts/backup_and_restore.sh backup all --delete-days 7 >> /var/log/mailcow-backup.log 2>&1
/opt/mailcow-backups 仍在同一台 VPS 上,只能防误删,不能防磁盘损坏和账号封禁。把备份加密同步到另一家对象存储或异地服务器,并定期使用空白测试机恢复。可复用VPS 备份恢复演练指南中的校验、保留和恢复验收方法。
恢复成功的标准包括:管理员可登录、历史邮件和附件完整、域名与 DKIM 配置存在、收发信正常,而不是脚本退出码为 0。
Mailcow 由多个网络服务组成,安全更新不能长期拖延。官方仓库提供 update.sh,不要自行对每个镜像执行无计划升级。
升级流程:
cd /opt/mailcow-dockerized
./update.sh --check
# 先执行完整备份并确认异地副本可读
./update.sh
docker compose ps
docker compose logs --tail=100 nginx-mailcow
docker compose logs --tail=100 postfix-mailcow
docker compose logs --tail=100 dovecot-mailcow
升级后验证后台、SOGo、IMAP 登录、SMTP 提交、外部收发、队列、TLS 和 DKIM。生产环境保持 stable 分支,不要直接切换 nightly。
dig +short MX example.com
nc -vz mail.example.com 25
docker compose logs --tail=200 postfix-mailcow
先确认 MX 指向正确主机名、A 记录指向当前 IP、入站 25 已开放。Cloudflare 橙云、旧 MX 和运营商封锁都可能导致超时。
nc -vz gmail-smtp-in.l.google.com 25
docker compose exec postfix-mailcow postqueue -p
docker compose logs --tail=300 postfix-mailcow
如果所有外部 25 都超时,优先联系 VPS 提供商确认出站封锁。不要把客户端提交端口 587 和服务器投递端口 25 混为一谈。
检查 A/PTR 正反向、SPF、DKIM、DMARC、IP 黑名单和邮件原始头。新 IP 不要突然批量发送,先用真实的一对一业务通信逐步建立信誉。更完整的错误码与送达排查见前文链接的邮件送达率指南。
dig +short A mail.example.com
docker compose logs --tail=300 acme-mailcow
sudo ss -lntp | grep -E ':80|:443'
确认域名直接解析到 Mailcow VPS、80/443 可达且未被其他服务占用。没有正确 IPv6 时删除错误的 AAAA 并关闭 Mailcow IPv6。
free -h
docker stats --no-stream
docker compose ps
journalctl -k --since '1 hour ago' | grep -i -E 'oom|killed process'
默认配置低于 6GiB 内存时,优先升级 VPS。紧急情况下可以按官方说明设置 SKIP_CLAMD=y、SKIP_FTS=y,但这会关闭病毒扫描或全文搜索,不应把它包装成零代价优化。
优先使用 993 IMAPS 和 587 Submission,确认用户名填写完整邮箱地址。检查时间、证书、密码与 Dovecot 日志:
docker compose logs --since=30m dovecot-mailcow
openssl s_client -connect mail.example.com:993 \
-servername mail.example.com </dev/null
- VPS 允许邮件服务,入站/出站 TCP 25 已实测
- 使用 KVM 等受支持虚拟化,默认配置至少 6GiB 内存加 1GiB Swap
-
mail.example.com的 A 与公网 IP PTR 正反向一致 - MX、SPF、DKIM、DMARC、autodiscover、autoconfig 已解析
- DNS 记录未被普通 CDN 代理
- 管理员默认密码已修改并启用两步验证
- TLS 证书有效,SMTP、IMAPS、Submission 端口可达
- 外部收信和向多家服务发信均测试成功
- SPF、DKIM、DMARC 在真实邮件头中均为 pass
- 完整备份已复制到异地,并完成空白机恢复演练
- 更新流程、日志位置和故障联系人已记录
Mailcow 能降低组件安装和日常管理门槛,但不能替你解决 IP 信誉、DNS 所有权和邮件合规。先把 25 端口、PTR 与 IP 历史查清,再部署和迁移正式邮箱,通常比装完以后四处申诉更省时间。
