目 录
[隐藏]

A fullstack but simple mail server (smtp, imap, antispam, antivirus…). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade.
        一个功能齐全而简单的邮件服务器,只需要简单的配置,不需要数据库。保持简单和版本化。易于部署和升级。

 

1.系统需求

推荐(Recommended):

  • 1 CPU
  • 1GB RAM

最低配置(Minimum):

  • 1 CPU
  • 512MB RAM

2.拉取 Docker 镜像

##
#  Get latest image

[root@d0o0bz ~]# docker pull tvial/docker-mailserver:latest

Trying to pull repository docker.io/tvial/docker-mailserver ... 
latest: Pulling from docker.io/tvial/docker-mailserver
f17d81b4b692: Pulling fs layer 
911909b5316e: Pulling fs layer 
fbc4a786db5d: Pulling fs layer 
......
f8cd433ffde8: Pull complete 
ba12d842ae98: Pull complete 
3cfa38e5ae88: Pull complete 
Digest: sha256:e09db271ee72890c8cad5d25119f817c5e00e672a4e14bb6281dc60c0a0ee2b8
Status: Downloaded newer image for docker.io/tvial/docker-mailserver:latest

3.下载文件

##
#  创建 docker-mailserver 目录

[root@d0o0bz ~]# cd /home/e.c./

[root@d0o0bz e.c.]# mkdir docker-mailserver

[root@d0o0bz e.c.]# cd docker-mailserver/

##
#  Download the docker-compose.yml, the .env and the setup.sh files:
#  setup.sh
[root@d0o0bz docker-mailserver]# wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh;

#  添加可执行权限
[root@d0o0bz docker-mailserver]# chmod a+x ./setup.sh

## 
#  docker-compose.yml
#  
[root@d0o0bz docker-mailserver]# wget -O docker-compose.yml https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml.dist

## 
#  .env
#  Environment variables 文件中有详细说明,可以参考
#
[root@d0o0bz docker-mailserver]# wget -O .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/.env.dist

[root@d0o0bz docker-mailserver]# ls -a
.  ..  docker-compose.yml  .env  setup.sh

4. 安装 Docker-Compose

##
#  Install Docker-Compose

[root@d0o0bz docker-mailserver]# sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   617    0   617    0     0    759      0 --:--:-- --:--:-- --:--:--   759
100 11.1M  100 11.1M    0     0   788k      0  0:00:14  0:00:14 --:--:-- 2220k


[root@d0o0bz docker-mailserver]# sudo chmod +x /usr/local/bin/docker-compose

[root@d0o0bz docker-mailserver]# docker-compose --version
docker-compose version 1.23.1, build b02f1306

5.编辑 .env

##
#  可不使用 .env ,直接修改 docker-compose.yml

HOSTNAME=mail
DOMAINNAME=d0o0bz.cn
CONTAINER_NAME=ec.mail

# 0 => Debug disabled
# 1 => Enables debug on startup
DMS_DEBUG=0

#  consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
#  使用统一的固定目录
ONE_DIR=1

# If you enable Fail2Ban, don't forget to add the following lines to your `docker-compose.yml`:
#    cap_add:
#      - NET_ADMIN
# Otherwise, `iptables` won't be able to ban IPs.
# 防暴力破解用户名密码的工具
ENABLE_FAIL2BAN=1

# 邮件杀毒工具
ENABLE_CLAMAV=1

# 垃圾邮件过滤器,在 Spamassassin section 编辑
ENABLE_SPAMASSASSIN=1

# empty => SSL disabled
# letsencrypt => Enables Let's Encrypt certificates
# custom => Enables custom certificates
# manual => Let's you manually specify locations of your SSL certificates for non-standard cases
# self-signed => Enables self-signed certificates
# SSL 认证
SSL_TYPE=letsencrypt 

6.编辑 docker-compose.yml

##
#  直接修改 docker-compose.yml,不使用 ".env"
#  edit “hostname” “domainname” “container_name” “volumes” “environment” 

version: '2'
services:
  mail:
    image: tvial/docker-mailserver:latest
    hostname: mail
    domainname: d0o0bz.cn
    container_name: mail
    ports:
    - "25:25"
    - "143:143"
    - "587:587"
    - "993:993"
    volumes:
    - /home/docker-mailserver/mail/:/var/mail
    - /home/docker-mailserver/mailstate:/var/mail-state
    - /home/docker-mailserver/config/:/tmp/docker-mailserver/
    - /etc/letsencrypt:/etc/letsencrypt
    environment:
    - ENABLE_SPAMASSASSIN=1
    - ENABLE_CLAMAV=1
    - ENABLE_FAIL2BAN=1
    - ONE_DIR=1
    - DMS_DEBUG=0
    - SSL_TYPE=letsencrypt
    cap_add:
    - NET_ADMIN
    - SYS_PTRACE
    restart: always

7.Let’s Encrypt SSL

生成 SSL / TLS 证书,请参考:


[为隐藏内容,请登录(login)以显示!]

8.启动容器

##
#  Start Container

 [root@d0o0bz docker-mailserver]# docker-compose -f docker-compose.yml up -d
WARNING: The POSTGREY_AUTO_WHITELIST_CLIENTS variable is not set. Defaulting to a blank string.
Creating network "docker-mailserver_default" with the default driver
Creating ec.mail ... done
##
#  
[root@d0o0bz docker-mailserver]# docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED              STATUS              PORTS                                                                                                                       NAMES
e5217a73454c        tvial/docker-mailserver:latest   "supervisord -c /e..."   About a minute ago   Up About a minute   0.0.0.0:25->25/tcp, 110/tcp, 0.0.0.0:143->143/tcp, 0.0.0.0:587->587/tcp, 465/tcp, 995/tcp, 0.0.0.0:993->993/tcp, 4190/tcp   ec.mail

9.创建邮件帐户

##
#  Create your mail accounts
#  ./setup.sh email add <user@domain> [<password>]

[root@d0o0bz docker-mailserver]# ./setup.sh email add e.c.admin@d0o0bz.cn <your password>

10.生成 DKIM keys

##
#  Generate DKIM keys 
#  ./setup.sh config dkim <keysize> (default: 2048)

[root@d0o0bz docker-mailserver]# ./setup.sh config dkim
Creating DKIM private key /tmp/docker-mailserver/opendkim/keys/d0o0bz.cn/mail.private
Creating DKIM KeyTable
Creating DKIM SigningTable
Creating DKIM TrustedHosts
##
#  /root/config/

[root@d0o0bz docker-mailserver]# ls /root/config/opendkim/keys/d0o0bz.cn/

mail.private  mail.txt

11.添加域名解析记录

Now the keys are generated, you can configure your DNS server by just pasting the content of config/opendkim/keys/domain.tld/mail.txt in your  domain.tld.hosts zone.

在域名解释中,添加:

主机记录记录类型记录值MX优先级
mailA<IP 或 域名>
mail._domainkeyTXTv=DKIM1;h=sha256;k=rsa;p=MIGfMA0GCSqGS…………3f2HjQIDAQAB
@MXmail.d0o0bz.cn.10
##
#  检查解释 dig @1.1.1.1 或 @8.8.8.8

[root@d0o0bz docker-mailserver]# dig -t txt mail._domainkey.d0o0bz.cn @1.1.1.1

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> -t txt mail._domainkey.d0o0bz.cn @1.1.1.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32893
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
;; QUESTION SECTION:
;mail._domainkey.d0o0bz.cn.	IN	TXT

;; ANSWER SECTION:
mail._domainkey.d0o0bz.cn. 600	IN	TXT	"v=DKIM1\;h=sha256\;k=rsa\;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD8MpFWx6iQ/VO94xVW6pXkXeut4EFOJ6ixr7931CqYEF4y/aHcwIP6Gf+JWSdap43spn/zHwwzNfHy/7p/JxORgymy3EESYZpJfEZXkDEhtDEXQOinWlGzIDmLgJmtCym+ujo6/oxYg+awrn9KXoFm2P6xVYp0Xg4YoFuISxU60wIDAQAB"

;; Query time: 577 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)

12.Exposed ports 开放端口

  • 25 receiving email from other mailservers
  • 465 SSL Client email submission
  • 587 TLS Client email submission
  • 143 StartTLS IMAP client
  • 993 TLS/SSL IMAP client
  • 110 POP3 client
  • 995 TLS/SSL POP3 client

13.重启容器

##
#  Restart the container
#  docker-compose down
#  docker-compose up -d mail

[root@d0o0bz docker-mailserver]# docker-compose -f docker-compose.yml down
WARNING: The POSTGREY_AUTO_WHITELIST_CLIENTS variable is not set. Defaulting to a blank string.
Stopping mail ... done
Removing mail ... done
Removing network docker-mailserver_default

[root@d0o0bz docker-mailserver]# docker-compose -f docker-compose.yml up -d
WARNING: The POSTGREY_AUTO_WHITELIST_CLIENTS variable is not set. Defaulting to a blank string.
Creating network "docker-mailserver_default" with the default driver
Creating mail ... done
##
#  
[root@d0o0bz docker-mailserver]# docker-compose ps
Name              Command               State                                  Ports                                
--------------------------------------------------------------------------------------------------------------------
mail   supervisord -c /etc/superv ...   Up      110/tcp, 0.0.0.0:143->143/tcp, 0.0.0.0:25->25/tcp, 4190/tcp,        
                                                465/tcp, 0.0.0.0:587->587/tcp, 0.0.0.0:993->993/tcp, 995/tcp       
##
#  
[root@d0o0bz docker-mailserver]# docker logs mail

2018-11-25 15:31:50,029 CRIT Supervisor running as root (no user in config file)
2018-11-25 15:31:50,029 INFO Included extra file "/etc/supervisor/conf.d/saslauth.conf" during parsing
2018-11-25 15:31:50,029 INFO Included extra file "/etc/supervisor/conf.d/supervisor-app.conf" during parsing
2018-11-25 15:31:50,074 INFO RPC interface 'supervisor' initialized
2018-11-25 15:31:50,075 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2018-11-25 15:31:50,075 INFO supervisord started with pid 1
2018-11-25 15:31:51,078 INFO spawned: 'mailserver' with pid 7

#
#
# docker-mailserver
#
#

Initializing setup
2018-11-25 15:31:51,118 INFO success: mailserver entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
Checking configuration
Configuring mail server
Starting Misc
Starting mail server
2018-11-25 15:31:58,576 INFO spawned: 'cron' with pid 151
2018-11-25 15:31:58,577 INFO success: cron entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
cron: started
2018-11-25 15:31:58,808 INFO spawned: 'rsyslog' with pid 153
2018-11-25 15:31:58,808 INFO success: rsyslog entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
rsyslog: started
2018-11-25 15:31:59,026 INFO spawned: 'dovecot' with pid 155
2018-11-25 15:31:59,027 INFO success: dovecot entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
dovecot: started
2018-11-25 15:31:59,235 INFO spawned: 'opendkim' with pid 160
2018-11-25 15:31:59,236 INFO success: opendkim entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
opendkim: started
2018-11-25 15:31:59,489 INFO spawned: 'opendmarc' with pid 168
2018-11-25 15:31:59,490 INFO success: opendmarc entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
opendmarc: started
2018-11-25 15:31:59,715 INFO spawned: 'postfix' with pid 180
2018-11-25 15:31:59,715 INFO success: postfix entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
postfix: started
2018-11-25 15:31:59,927 INFO spawned: 'fail2ban' with pid 187
2018-11-25 15:31:59,928 INFO success: fail2ban entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
fail2ban: started
2018-11-25 15:32:00,193 INFO spawned: 'clamav' with pid 205
2018-11-25 15:32:00,194 INFO success: clamav entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
clamav: started
2018-11-25 15:32:00,426 INFO spawned: 'changedetector' with pid 211
2018-11-25 15:32:00,427 INFO success: changedetector entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
changedetector: started
2018-11-25 15:32:00,692 INFO spawned: 'amavis' with pid 222
2018-11-25 15:32:00,692 INFO success: amavis entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
amavis: started

#
# mail.d0o0bz.cn is up and running
#

2018-11-25 15:32:01,479 INFO reaped unknown pid 226
2018-11-25 15:32:03,469 INFO reaped unknown pid 225
Nov 25 15:32:04 mail amavis[222]: starting. /usr/sbin/amavisd-new at mail.d0o0bz.cn amavisd-new-2.10.1 (20141025), Unicode aware
Nov 25 15:32:06 mail amavis[222]: Net::Server: Group Not Defined.  Defaulting to EGID '111 111'
Nov 25 15:32:06 mail amavis[222]: Net::Server: User Not Defined.  Defaulting to EUID '109'
Nov 25 15:32:06 mail amavis[222]: Module Amavis::Conf        2.404
Nov 25 15:32:06 mail amavis[222]: Module Archive::Zip        1.59
Nov 25 15:32:06 mail amavis[222]: Module BerkeleyDB          0.55
Nov 25 15:32:06 mail amavis[222]: Module Compress::Raw::Zlib 2.069
Nov 25 15:32:06 mail amavis[222]: Module Compress::Zlib      2.069001
Nov 25 15:32:06 mail amavis[222]: Module Crypt::OpenSSL::RSA 0.28
Nov 25 15:32:06 mail amavis[222]: Module DB_File             1.835
Nov 25 15:32:06 mail amavis[222]: Module Digest::MD5         2.54
Nov 25 15:32:06 mail amavis[222]: Module Digest::SHA         5.95_01
Nov 25 15:32:06 mail amavis[222]: Module Encode              2.80_01
Nov 25 15:32:06 mail amavis[222]: Module File::Temp          0.2304
Nov 25 15:32:06 mail amavis[222]: Module IO::Socket::INET6   2.72
Nov 25 15:32:06 mail amavis[222]: Module IO::Socket::IP      0.37
Nov 25 15:32:06 mail amavis[222]: Module MIME::Entity        5.508
Nov 25 15:32:06 mail amavis[222]: Module MIME::Parser        5.508
Nov 25 15:32:06 mail amavis[222]: Module MIME::Tools         5.508
Nov 25 15:32:06 mail amavis[222]: Module Mail::DKIM::Verifier 0.4
Nov 25 15:32:06 mail amavis[222]: Module Mail::Header        2.18
Nov 25 15:32:06 mail amavis[222]: Module Mail::Internet      2.18
Nov 25 15:32:06 mail amavis[222]: Module Mail::SPF           v2.009
Nov 25 15:32:06 mail amavis[222]: Module Mail::SpamAssassin  3.004002
Nov 25 15:32:06 mail amavis[222]: Module Net::DNS            1.07
Nov 25 15:32:06 mail amavis[222]: Module Net::LibIDN         0.12
Nov 25 15:32:06 mail amavis[222]: Module Net::Server         2.008
Nov 25 15:32:06 mail amavis[222]: Module NetAddr::IP         4.079
Nov 25 15:32:06 mail amavis[222]: Module Razor2::Client::Version 2.84
Nov 25 15:32:06 mail amavis[222]: Module Scalar::Util        1.4202
Nov 25 15:32:06 mail amavis[222]: Module Socket              2.020_03
Nov 25 15:32:06 mail amavis[222]: Module Socket6             0.27
Nov 25 15:32:06 mail amavis[222]: Module Time::HiRes         1.9733
Nov 25 15:32:06 mail amavis[222]: Module URI                 1.71
Nov 25 15:32:06 mail amavis[222]: Module Unix::Syslog        1.1
Nov 25 15:32:06 mail amavis[222]: Amavis::ZMQ code     NOT loaded
Nov 25 15:32:06 mail amavis[222]: Amavis::DB code      loaded
Nov 25 15:32:06 mail amavis[222]: SQL base code        NOT loaded
Nov 25 15:32:06 mail amavis[222]: SQL::Log code        NOT loaded
Nov 25 15:32:06 mail amavis[222]: SQL::Quarantine      NOT loaded
Nov 25 15:32:06 mail amavis[222]: Lookup::SQL code     NOT loaded
Nov 25 15:32:06 mail amavis[222]: Lookup::LDAP code    NOT loaded
Nov 25 15:32:06 mail amavis[222]: AM.PDP-in proto code loaded
Nov 25 15:32:06 mail amavis[222]: SMTP-in proto code   loaded
Nov 25 15:32:06 mail amavis[222]: Courier proto code   NOT loaded
Nov 25 15:32:06 mail amavis[222]: SMTP-out proto code  loaded
Nov 25 15:32:06 mail amavis[222]: Pipe-out proto code  NOT loaded
Nov 25 15:32:06 mail amavis[222]: BSMTP-out proto code NOT loaded
Nov 25 15:32:06 mail amavis[222]: Local-out proto code loaded
Nov 25 15:32:06 mail amavis[222]: OS_Fingerprint code  NOT loaded
Nov 25 15:32:06 mail amavis[222]: ANTI-VIRUS code      loaded
Nov 25 15:32:06 mail amavis[222]: ANTI-SPAM code       loaded
Nov 25 15:32:06 mail amavis[222]: ANTI-SPAM-EXT code   NOT loaded
Nov 25 15:32:06 mail amavis[222]: ANTI-SPAM-C code     NOT loaded
Nov 25 15:32:06 mail amavis[222]: ANTI-SPAM-SA code    loaded
Nov 25 15:32:06 mail amavis[222]: Unpackers code       loaded
Nov 25 15:32:06 mail amavis[222]: DKIM code            NOT loaded
Nov 25 15:32:06 mail amavis[222]: Tools code           NOT loaded
Nov 25 15:32:06 mail amavis[222]: Found $file            at /usr/bin/file
Nov 25 15:32:06 mail amavis[222]: No $altermime,         not using it
Nov 25 15:32:06 mail amavis[222]: Internal decoder for .mail
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .Z    at /bin/uncompress
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .gz   at /bin/gzip -d
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .bz2  at /bin/bzip2 -d
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .xz   at /usr/bin/xz -dc
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .lzma at /usr/bin/xz -dc --format=lzma
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .lrz  at /usr/bin/lrzip -q -k -d -o -
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .lzo  at /usr/bin/lzop -d
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .lz4  at /usr/bin/lz4c -d
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .rpm  at /usr/bin/rpm2cpio
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .cpio at /bin/pax
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .tar  at /bin/pax
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .deb  at /usr/bin/ar
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .rar  at /usr/bin/unrar-free
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .arj  at /usr/bin/arj
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .arc  at /usr/bin/nomarch
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .zoo  at /usr/bin/zoo
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .doc  at /usr/bin/ripole
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .cab  at /usr/bin/cabextract
Nov 25 15:32:06 mail amavis[222]: Internal decoder for .tnef
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .zip  at /usr/bin/7za
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .kmz  at /usr/bin/7za
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .7z   at /usr/bin/7zr
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .jar  at /usr/bin/7z
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .swf  at /usr/bin/7z
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .lha  at /usr/bin/7z
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .iso  at /usr/bin/7z
Nov 25 15:32:06 mail amavis[222]: Found decoder for    .exe  at /usr/bin/unrar-free; /usr/bin/arj
Nov 25 15:32:06 mail amavis[222]: No decoder for       .F   
Nov 25 15:32:06 mail amavis[222]: Using primary internal av scanner code for ClamAV-clamd
Nov 25 15:32:06 mail amavis[222]: Found secondary av scanner ClamAV-clamscan at /usr/bin/clamscan
Nov 25 15:32:06 mail amavis[222]: Deleting db files __db.003,nanny.db,snmp.db,__db.001,__db.002 in /var/lib/amavis/db
Nov 25 15:32:06 mail amavis[222]: Creating db in /var/lib/amavis/db/; BerkeleyDB 0.55, libdb 5.3
Nov 25 15:32:12 mail postfix/master[985]: daemon started -- version 3.1.8, configuration /etc/postfix
Nov 25 15:33:42 mail dovecot: imap-login: Login: user=<e.c.admin@d0o0bz.cn>, method=PLAIN, rip=223.104.1.244, lip=172.17.0.2, mpid=1335, TLS, session=<ZbL88H57p37faAH0>
Nov 25 15:33:42 mail dovecot: imap-login: Login: user=<e.c.admin@d0o0bz.cn>, method=PLAIN, rip=223.104.1.244, lip=172.17.0.2, mpid=1336, TLS, session=<3LL88H57pn7faAH0>
Nov 25 15:33:43 mail dovecot: imap(e.c.admin@d0o0bz.cn): Logged out in=146 out=808
Nov 25 15:33:53 mail dovecot: imap-login: Login: user=<e.c.admin@d0o0bz.cn>, method=PLAIN, rip=223.104.1.244, lip=172.17.0.2, mpid=1379, TLS, session=<qEqf8X57qH7faAH0>
##
#  

参考资料:
https://github.com/tomav/docker-mailserver