ISP-style mailserver based on Postfix, Dovecot and SpamAssassin with a database backend
2.4K
See Mailu for a similar/better project
Dockerfile to build a multiple domain mail server using Postfix and Dovecot with IMAP and POP3 (like the one of a hosting provider).
This image is based on the ISPmail tutorial of Christoph Haas.
Additional the entrypoint of this images is based on GitLab Image of Sameer Naik.
There are some differences to the tutorial:
TODO: Docker compose
To avoid losing any data, you should mount a volume at:
/dataThere you will find 3 subdirectories:
/data/maildir - contains received and send emails/data/log - contains logs of mail server/data/ssl - contains SSL certificates of mail serverVolumes can be mounted in docker by specifying the -v option in the docker run command.
docker run --name isp-mail -d \
-v /srv/docker/isp-mail:/data \
bboehmke/isp-mail:latest
If the server should be reachable from outside the host system, there are some ports that must be forwarded.
This mail server uses a database to store existing mail address and redirection. You can configure this image to use either MySQL or PostgreSQL.
Note: The structure of the database is shown in Database Structure
Assuming that the PostgreSQL server host is 192.168.1.42 with user mail,
password password and the dtabase name mailDB
docker run --name isp-mail -d \
-e DB_TYPE=postgresql \
-e DB_HOST=192.168.1.42 \
-e DB_NAME=mailDB \
-e DB_USER=mail \
-e DB_PASS=password \
-v /srv/docker/isp-mail:/data \
bboehmke/isp-mail:latest
If a postgresql container is linked, only the DB_TYPE, DB_HOST and
DB_PORT settings are automatically retrieved using the linkage. You may
still need to set other database connection parameters such as the DB_NAME,
DB_USER, DB_PASS and so on.
To illustrate linking with a postgresql container, we will use the official postgresql image. When using postgresql image in production you should mount a volume for the postgresql data store. Please refer the postgresql image for details.
First, start the postgresql container:
docker run --name mail-postgresql \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=mailDB \
-e POSTGRES_USER=mail \
postgres
The above command will create a database named mailDB and also create a user
named mail with the password password with full/remote access to the
mailDB database.
Now start the mail container:
docker run --name isp-mail -d \
--link mail-postgresql:postgresql \
-v /srv/docker/isp-mail:/data \
bboehmke/isp-mail:latest
Here the image will also automatically fetch the DB_NAME, DB_USER and
DB_PASS variables from the postgresql container as they are specified in the
docker run command for the postgresql container. This is made possible using
the magic of docker links and works with the following images:
Assuming that the MySQL server host is 192.168.1.42 with user mail,
password password and the dtabase name mailDB
docker run --name isp-mail -d \
-e DB_TYPE=mysql \
-e DB_HOST=192.168.1.42 \
-e DB_NAME=mailDB \
-e DB_USER=mail \
-e DB_PASS=password \
-v /srv/docker/isp-mail:/data \
bboehmke/isp-mail:latest
If a mysql container is linked, only the DB_TYPE, DB_HOST and DB_PORT
settings are automatically retrieved using the linkage. You may still need
to set other database connection parameters such as the DB_NAME, DB_USER,
DB_PASS and so on.
To illustrate linking with a mysql container, we will use the official mysql image. When using mysql image in production you should mount a volume for the mysql data store. Please refer the README of the mysql image for details.
First, start the mysql container:
docker run --name mail-mysql \
-e MYSQL_PASSWORD=password \
-e MYSQL_DATABASE=mailDB \
-e MYSQL_USER=mail \
-e MYSQL_RANDOM_ROOT_PASSWORD=true \
mysql
The above command will create a database named mailDB and also create a user
named mail with the password password with full/remote access to the
mailDB database.
Now start the mail container:
docker run --name isp-mail -d \
--link mail-mysql:mysql \
-v /srv/docker/isp-mail:/data \
bboehmke/isp-mail:latest
Here the image will also automatically fetch the DB_NAME, DB_USER and
DB_PASS variables from the mysql container as they are specified in the
docker run command for the mysql container. This is made possible using the
magic of docker links and works with the following images:
This images requires a SSL certificate to secure the communication with the mail server.
The key file and the certificate should be stored in the /data/ssl directory
with the name mail.key and mail.crt. Note: The name of the files can changed
with SSL_KEY and SSL_CRT.
The SSL of this image is configured to use perfect forward security. This
requires a dhparam file wich is automatically recreated on each container start.
The default size of this file is 1024 bits but you can increase this with
SSL_DH_PARAM_LENGTH.
Please refer the docker run command options for the --env-file flag where
you can specify all required environment variables in a single file.
This will save you from writing a potentially long docker run command.
Alternatively you can use docker-compose.
true to enable entrypoint debugging.Note: This structure differs from the one of the tutorial!
The database of this mail server contains of 3 tables:
| Table | Description |
|---|---|
| virtual_domains | List of domains that are handled by this mail server |
| virtual_users | List of users (mail accounts) |
| virtual_aliases | List of mail redirection |
| Column | Description |
|---|---|
| id | Id of this domain (automatic created) |
| name | Name of the domain (eg mail.com |
| Column | Description |
|---|---|
| id | Id of this user (automatic created) |
| domain_id | Id of the domain this user is for (must exist in virtual_domains) |
| name | Name of the user (eg if the address is [email protected] the name is user) |
| password | Hash of the user password |
| Column | Description |
|---|---|
| id | Id of this alias (automatic created) |
| domain_id | Id of the domain this user is for (must exist in virtual_domains) |
| source | Local name of the email address (eg if the address is [email protected] the source is admin) |
| destination | Destination of the redirection (eg [email protected] or an external address like [email protected]) |
The database can be administered directly via a Web-based interface like phpPgAdmin (PostgreSQL) or phpMyAdmin (MySQL) or via a set of integrated shell-scripts.
All shell-scripts can be executed in an existing container:
docker exec -it <container> <...>
Or by a temporary container:
docker run -it --rm --link database:<mysql|postgresql> bboehmke/isp-mail <...>
Possible commands are described in the following sub-sections.
domains -l | -a <domain.xx> | -d <domain.xx>
-l
-a <domain.xx>
-d <domain.xx>
docker exec -it <container> domains -a domain.xxusers -l | -a <[email protected][:password]> | -d <[email protected]>
-l
-a <[email protected][:password]>
name for domain.xxpassword is omitted, the script will ask for a password.-p <[email protected][:password]>
password is omitted, the script will ask for a password.-d <[email protected]>
name for domain.xx-D <[email protected]>
docker exec -it <container> users -a [email protected]:passwordforwards -l | -a <[email protected]:[email protected]> | -d <[email protected]>
-l
-a <[email protected]:[email protected]>
[email protected] to destination [email protected]-d <[email protected]>
[email protected]docker exec -it <container> forwards -a [email protected]:[email protected]Before you upgrade the image you should create a backup of the /data volume
and the database.
To upgrade to a newer version of the image follow this steps:
docker pull bboehmke/isp-mail:latest
docker stop isp-mail
docker rm isp-mail
docker run --name isp-mail -h isp-mail -d \
[OPTIONS] \
bboehmke/isp-mail:latest
The following features are planned for the future
Content type
Image
Digest
sha256:4ee3c962a…
Size
288.9 MB
Last updated
about 7 years ago
docker pull bboehmke/isp-mail