A set of docker images and instructions that can be used to set up a simple mail server for a single user.
Features:
Expected set up time: 1 hour
Add this repo as a submodule
git submoudle add https://github.com/vikstrous/mailserver
git submodule update --init
Link the docker compose file ln -s ./mailserver/docker-compose.yml
Create the directories used for secrets: mkdir -p ./cert ./dkim
Create a file called ./env
filling out the following data:
mail_for_fqdn=
mailserver_fqdn=
user=
mail.
subdomain to make autodiscovery work easily in mail clients. In other words, if mail_for_fqdn
is example.com mailserver_fqdn
is mail.example.comGenerate a password hash for auth
python3 -c 'import crypt; print(crypt.crypt("password", crypt.mksalt(crypt.METHOD_SHA512)))'
, replacing password
with your password./env
as pass=$6$...
Generate a DKIM key
opendkim-genkey --hash-algorithms sha256 --bits 2048 --domain $MAILSERVER_FQDN --directory ./dkim --selector default --restrict
./dkim/default.private
dkim/default.txt
- you will use this for your DKIM DNS recordscurl https://get.docker.com | sudo sh
(known to work with docker 1.12)sudo usermod -aG docker your-user
if not using the root userGet docker compose:
curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
default._domainkey
./dkim/default.txt
generated earlier for the value of the TXT record@
and value "v=spf1 mx -all"
_dmarc
and value v=DMARC1; p=reject; rua=mailto:dmarc@$MAIL_FOR_FQDN; ruf=mailto:dmarc-violation@$MAIL_FOR_FQDN; sp=reject; fo=1; aspf=s; adkim=s; pct=100
Wait for the DNS A record to propagate. Try resolving your hostname from your server a few times until it works, then choose one of the following options to get a TLS cert:
Using Let's Encrypt
docker run -it --rm -p 443:443 -p 80:80 --name certbot -v $(pwd)/out:/out --entrypoint sh quay.io/letsencrypt/letsencrypt:latest -c "certbot certonly --non-interactive --standalone --agree-tos --email a@example.com -d $MAILSERVER_FQDN && tar -c /etc/letsencrypt/archive/$MAILSERVER_FQDN > /out/certs.tar"
cd out
tar -xvf certs.tar
etc/letsencrypt/archive/$MAILSERVER_FQDN/fullchain1.pem
and etc/letsencrypt/archive/$MAILSERVER_FQDN/privkey1.pem
. Copy them to your project as ./cert/cert.pem
and ./cert/key.pem
respectivelyOr with a real CA
Generate the key and csr
openssl genrsa -out ./cert/key.pem 4096
openssl req -new -key ./cert/key.pem -out ./cert/csr.pem
./cert/cert.pem
Or with a self signed cert
openssl req -x509 -newkey rsa:4096 -keyout ./cert/key.pem -out ./cert/cert.pem -days 365
Now that everything is ready, commit all your secrets to git, push them, then
clone the repo onto your server and run docker-compose up -d
. Sorry about the
lame secret management. Encrypting the secrets is left as an exercise to the
reader.
sieve.example
from the root of this repo into ./sieve/sieve
in your repo then modify it to fit your needsIn your repo:
cd mailserver
git pull
cd ..
git add mailserver
git commit -m 'update mailserver'
git push
On the server:
docker-compose up --build -d
There is no easy way to do this without down time, so here's one way you can do it while having minimal down time
docker-compose up --force-recreate -d
to update the serverThe down time should happen only between step 8 and the end of step 9.