1小时从零搭建私有邮件服务器(Docker实战)

2 次阅读 0 点赞 0 评论 9 分钟原创技术教程

本文手把手教你使用 Docker 和 Mailu 部署全功能私有邮件服务器。涵盖环境准备、Compose 配置、DNS 解析(MX/SPF/DKIM)、SSL 证书及反垃圾策略设置。学完即可独立运行具备收发邮件、Webmail 访问和防伪造机制的邮件服务,彻底摆脱第三方商业邮箱限制。

#Docker #邮件服务器 #私有化部署 #运维实战 #Linux #DNS配置 #Mailu

手把手用 Docker 搭建私有邮件服务器:从域名解析到 Webmail 访问

做后端开发这些年,我遇到过不少「邮件服务」相关的需求:注册验证码、密码重置、业务通知……一开始大家都会想到用阿里云、腾讯云的邮件推送,或者接入第三方 API。但如果你像我一样,偶尔会需要给内部团队收发邮件、想给个人域名配个 @yourname.com 的邮箱、或者单纯想掌控自己的通信基础设施,租商业邮箱不仅贵,限制也多。

今天带你用 Mailu —— 一个用 Docker 打包的全功能邮件服务器方案 —— 在一台云服务器上从零搭建能正式对外收发邮件的服务。学完这篇,你会经历完整的环境准备、Docker Compose 配置、DNS 记录设置(MX/SPF/DKIM)、SSL 证书配置,最后用 Webmail 成功收发第一封邮件。

一、你需要准备什么

这篇教程假设你已经具备以下条件:

  1. 一台 Linux 服务器:推荐 Ubuntu 20.04/22.04 或 Debian 11+,至少 2 核 2G 内存。邮件服务组件多(反垃圾、杀毒都有),1G 会非常吃力。
  2. 一个自有域名:比如 mydomain.com,邮件必须绑定域名才能正常投递。
  3. DNS 管理权限:需要能在域名服务商后台添加 TXT、MX 等记录。
  4. 基础 Docker 知识:知道 docker-compose up -d 是干什么的就行,我会把每个配置参数拆开讲。

为什么选 Mailu?市面上也有 Modoboa、iRedMail 等方案,但 Mailu 的优势在于:纯 Docker 原生部署,不侵入宿主机环境;组件清晰可替换;而且自带 Let's Encrypt 集成和反垃圾引擎,开箱即用。

二、快速上手:三步起服务

Mailu 官方提供了一个在线配置生成器,但为了让你知其所以然,我们手动写出最小可用的 docker-compose.yml 和 .env 文件。

步骤 1:创建目录和配置文件

bash 复制代码
mkdir -p ~/mailu && cd ~/mailu

cat > .env << 'EOF'
DOMAIN=mydomain.com
HOSTNAME=mail
TLS_FLAVOR=letsencrypt
DB_FLAVOR=sqlite
INITIAL_ADMIN_ACCOUNT=admin
INITIAL_ADMIN_PW=YourStrongP@ssw0rd!
ANTISPAM_SPAM_THRESHOLD=5
ANTISPAM_GREYLISTING=on
EOF

关键参数解释:

  • TLS_FLAVOR=letsencrypt:自动申请 Let's Encrypt 证书。若已有证书,可改为 cert 并手动挂载。
  • HOSTNAME=mail:主机名最终为 mail.mydomain.com,后续 DNS 记录会用到。
  • 环境变量通过 .env 集中管理,所有容器启动时自动读取,避免硬编码。

步骤 2:编写 docker-compose.yml

在 ~/mailu 目录下创建 docker-compose.yml:

yaml 复制代码
version: "3.8"
services:
  antispam:
    image: ghcr.io/mailu/rspamd:master
    restart: always
    env_file: .env
    volumes: ["./data/rspamd:/data"]
  webmail:
    image: ghcr.io/mailu/webmail:master
    restart: always
    env_file: .env
    depends_on: [front]
    volumes: ["./data/webmail:/data"]
  admin:
    image: ghcr.io/mailu/admin:master
    restart: always
    env_file: .env
    depends_on: [front, db]
    volumes: ["./data/admin:/data"]
  db:
    image: ghcr.io/mailu/postgresql:master
    restart: always
    env_file: .env
    volumes: ["./data/db:/data"]
  front:
    image: ghcr.io/mailu/nginx:master
    restart: always
    env_file: .env
    ports:
      - "80:80"
      - "443:443"
      - "25:25"
      - "465:465"
      - "587:587"
      - "993:993"
    volumes:
      - "./data/certs:/certs"
      - "./dkim:/dkim"

front 服务暴露多个端口对应不同协议:

  • 25/465/587 → SMTP(发邮件)
  • 110/995 → POP3(收邮件,较少用)
  • 143/993 → IMAP(推荐,支持多端同步)

该容器集成 Nginx,负责 TLS 加解密、协议转发,封装了复杂的路由配置。

步骤 3:启动服务

bash 复制代码
docker-compose up -d

首次启动会自动初始化数据库、生成 DKIM 密钥、创建管理员账号。查看日志确认状态:

bash 复制代码
docker-compose logs -f front
docker-compose logs -f admin

三、实战:配置 DNS 与管理域名

邮件服务器最容易踩坑的就是 DNS。记录缺失或错误会导致邮件被 Gmail、Outlook 等直接拒收。

3.1 必须添加的 DNS 记录

在域名管理后台添加:

记录类型 名称 值 说明
A mail 服务器IP 邮件服务器主机
MX @ mail.mydomain.com. 告诉外界邮件投递地址
TXT @ v=spf1 mx ~all SPF 防伪造发件人
TXT mail._domainkey v=DKIM1; k=rsa; p=... DKIM 签名
TXT _dmarc v=DMARC1; p=none; rua=mailto:admin@mydomain.com DMARC 策略

DKIM 公钥获取方式:

bash 复制代码
cat ./dkim/mailu/mydomain.com.dns

将输出的 TXT 值粘贴至 DNS 后台。

3.2 添加域名与创建用户

访问 https://mail.mydomain.com/admin 使用初始账号登录。

  1. Domains → Add Domain:填入域名,系统自动校验 DNS(生效需 10 分钟至 2 小时)。
  2. Users → Add User:创建邮箱 you@mydomain.com 并设置强密码。

四、收发第一封邮件

访问 https://mail.mydomain.com/webmail 登录。内置 Roundcube 界面,操作直观。
测试发件:给自己发邮件,通常秒到。
测试收件:从 Gmail/QQ 发邮件至该地址,若 DNS 正确即可正常接收。

发不出去?排查 25 端口:
多数云厂商默认封禁 25 端口。需在控制台申请解封,或改用第三方 SMTP(SendGrid/SES)做转发。Mailu 反垃圾与管理后台仍可正常使用。

五、常见问题速查

Q:证书申请失败?
确保 80 端口可访问且域名解析生效。先 curl -I http://mail.mydomain.com 确认返回 200,再重启 front 容器。

Q:邮件被标记为垃圾邮件?
90% 因 DNS 不完整。检查 SPF/DKIM/DMARC。使用 mail-tester.com 评分,9 分以上即可进主流收件箱。

Q:想换数据库?
改 .env 中 DB_FLAVOR=postgresql 或 mysql 并配置连接串。生产环境强烈建议替换 SQLite。

Q:备份方案?
打包 ./data 目录:tar -czf mailu-backup.tar.gz ./data。恢复时解压至同路径,迁移极方便。

六、总结

完成以上步骤,你已经掌握了一套私有邮件服务器的标准化部署流程。Mailu 将 Nginx、Postfix、Dovecot、Rspamd 等组件统一编排,只需聚焦业务配置。建议后续探索 API 批量管理,并启用 Passkey 登录提升安全性。

配置中遇到任何问题,欢迎交流。

最后更新:2026-10-24T10:04:52

评论 (0)

发表评论

blog.comments.form.loading
0/500

暂无评论,快来发表第一条评论吧!