A quick way to host your own mail.
This is a
docker-compose-based environment for setting up a personal
mailserver as quickly and simply as possible. Included are a collection of
components, bundled together via a compose file, which provide a simple but
fully-functional mail stack.
The framework is built from the following components:
The default configuration is fairly minimal but will be enough to get started straight out of the box, but can be tweaked by modifying the config files in the repository.
You will need:
The configuration expects you to have SSL certificates, and will look for them
in Certbot's default directory. (
An example of using
certbot to obtain a certificate using your Cloudflare
docker run -ti --rm -v /etc/letsencrypt:/etc/letsencrypt \ certbot/dns-cloudflare \ certonly --dns-cloudflare \ --dns-cloudflare-credentials /etc/letsencrypt/renewal/cloudflare.ini \ -d mail.MYDOMAIN.XYZ
This assumes that you have written your cloudflare credentials to
/etc/letsencrypt/renewal/cloudflare.ini - more information is available on
this and other ways of getting free SSL certificates in the documtation for
git clone https://git.sd.ai/simon/simple-selfhosted-mail
All following comands are relative to the root directory of the repository.
You'll want to generate a DKIM key for your domain, as follows:
cd dkim ./dkim_gen_key.sh MYDOMAIN.XYZ cat MYDOMAIN.XYZ/dns
MYDOMAIN.XYZ/dns contains the DNS records you need to add to your
domain for SPF, DKIM and DMARC.
In your DNS, you will need to add:
Arecord for your server's public IP. e.g.
MXrecord for your domain, pointing at your
TXTrecord for DKIM
SPFrecords in the root of your domain for SPF
TXTrecord containing your DMARC record
Important: The reverse DNS for your IP should match the
A record you want to
use. Without this, you will look spammy to other mail servers and may experience
The entries generated in the
dns file should work without modification, and
should be added as-is unless you know what you are doing.
You need three environment variables set before you bring up the mail stack:
MAIL_HOSTNAMEshould be the hostname of your mail server, and should match your reverse DNS
SSL_DOMAINis the name of the directory in
/etc/letsencrypt/livethat contains your SSL certificate.
MAIL_HOSTNAMEif your certificate just has one host, but if you have multiple hosts in the same cert then it may be something different.
MYSQL_PASSWORDis the password used to initialise and connect to the MariaDB database. (The username will be
The easiest way to set these up is to add them to your
export MAIL_HOSTNAME=mail.MYDOMAIN.XYZ export SSL_DOMAIN=mail.MYDOMAIN.XYZ export MYSQL_PASSWORD=some_secure_password
Don't forget to reload your
.bashrc when done:
docker-compose build command will download all of the necessary base
images and configure them. Run this inside your repository.
You can then bring everything up with
docker-compose up -d
There are user-management scripts in the
bin subdirectory, which call
docker-compose so should be run from the repository root. These commands are
To create the first user you'll want to run:
You will be prompted for a password.
Rainloop webmail should be listening on your mail server now. You will need to set up your domain via the admin interface before you can log in:
securityand change the admin password!
domainsand add your domain:
Test- it should say everything is OK
Allow sieve scriptsand
Allow custom user script
Testagain - it should test the sieve configuration and verify that it is OK
TODO: Add some screenshots!
NOTE: The internal ports specified above are different to the ports externally published, which are the standard IMAP and SMTP ports. The internal ports are on numbers >1024 so that the processes can be run as a non-root user.
This will have configured Rainloop to handle your domain, so that it knows how to send and receive mail from the rest of the stack.
https://mail.MYDOMAIN.XYZ/ and log in as the user you created earlier.
You may want to use the DKIM tester at (http://www.appmaildev.com/en/dkim) to verify that your setup is correctly signing messages.
To update and rebuild the stack, run:
git pull docker-compose build --pull
There are a couple of things that it helps to be aware of:
Your mail and settings are stored in Docker volumes defined in
docker-compose.yml. Please be careful when running commands such as
docker-compose down (don't run it with the
-v parameter) or
as these may delete volumes, which will wipe out your mail!
If you rebuild any of the containers in the stack and then re-run
docker-compose up, you may see errors about volumes already being mounted.
When you rebuild, you must run
docker-compose down before bringing it back up
It may be that the programs running inside your containers can't read your SSL
certificates, due to the fact that they run as their own user (e.g. users
haraka.) The SSL certificates are bind-mounted into the running
containers and inherit the permissions that they have on disk.
You may need to change the permissions on the files to support this. If you are
confident that only you have access to the server, running
chmod a+r /etc/letsencrypt/archive/mail.YOURDOMAIN.XYZ/* will work, but be
aware of the security implications of doing this.
Multiple domains are supported. Simply add another user with
Feel free to make a PR or open issues. Feedback is good.