Table of Contents
Current situation
Mailcow and Traefik are installed as described in the excellent instructions of goneuland.de for mailcow. The only drawback of this guide is that after adding an email domain you still have to make manual adjustments in the docker-compose.override.yml file and mailcow has to be redeployed via docker-compose afterwards. The workaround is that an extra container generates the Traefik configuration from the Mailcow database and makes it available as an Http provider.
Http Provider
The dynamic Traefik configuration is generated by a small Flask webapp. The code can be found here: https://github.com/olqs/mailcow-traefik-cert-helper
Docker Compose and new container
In the file “docker-compose.override.yml” you have to change two things.
First, comment out all entries that configure SSL termination, or delete them. The Traefik router that does this is called nginx-mailcow-secure.
Services:
nginx-mailcow:
Labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx-mailcow.entrypoints=http"
- "traefik.http.routers.nginx-mailcow.rule=HostRegexp('{host:(autodiscover|autoconfig|webmail|mail|email).+}')"
- "traefik.http.middlewares.nginx-mailcow-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.nginx-mailcow.middlewares=nginx-mailcow-https-redirect"
# - "traefik.http.routers.nginx-mailcow-secure.entrypoints=https"
# - "traefik.http.routers.nginx-mailcow-secure.rule=Host('mail.worli.info')" ###### specify your FQDN here #####
# - "traefik.http.routers.nginx-mailcow-secure.tls=true"
# - "traefik.http.routers.nginx-mailcow-secure.tls.domains [0] .main=mail.worli.info" ###### adjust to your FQDN from above #####
# - "traefik.http.routers.nginx-mailcow-secure.tls.domains [0] .sans=imap.worli.info, smtp.worli.info, pop3.worli.info" ## Customize domain ##
# - "traefik.http.routers.nginx-mailcow-secure.service=nginx-mailcow"
# - "traefik.http.routers.nginx-mailcow-secure.tls.certresolver=http"
- "traefik.http.services.nginx-mailcow.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
Networks:
proxy:
Add the container that provides the configuration, the database password is taken with the configuration from the mailcow.conf:
mailcow-traefik-cert-helper:
image: olqs/mailcow-traefik-cert-helper
container_name: mailcowdockerized_mailcow-traefik-cert-helper
restart: unless-stopped
Networks:
proxy:
Aliases:
- mailcow-traefik-cert-helper
mailcow-network:
Aliases:
- mailcow-traefik-cert-helper
environment:
- MYSQL_DATABASE_PASSWORD=${DBPASS}
Adjust static Traefik configuration
Extend the configuration point “providers” with the Http provider.
Provider:
Docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: "./dynamic_conf.yml"
watch: true
http:
endpoint: http://mailcowdockerized_mailcow-traefik-cert-helper:5000/
Certdumper Container
The certdumper container used in the instructions has the possibility to either extract all certificates generated in Traefik or a manually maintained list of certificates from the acme.json. In addition, mailcow must have a file “domains” in the certificate folders that are generated, which contains a space-separated list of all domains for which the certificate is valid.
The container image was adapted by me so that the “domains” file is created and you can now specify via an environment variable that only domains that start with a defined text are exported. For the code changes, I created a pull request, but at the time of article creation, that was not yet accepted. My customized source code can be found here: https://github.com/olqs/traefik-certs-dumper
certdumper:
image: olqs/traefik-certs-dumper
container_name: mailcowdockerized_traefik_certdumper
restart: unless-stopped
network_mode: none
command: --restart-containers mailcowdockerized_postfix-mailcow_1.mailcowdockerized_dovecot-mailcow_1
Volumes:
# mount the folder which contains Traefik's 'acme.json' file
# in this case Traefik is started from its own docker-compose in .. /traefik
- /data/traefik:/traefik:ro
#mount mailcow's SSL folder
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/assets/ssl:/output:rw
environment:
# only change this, if you're using another domain for mailcow's web frontend compared to the standard config
- DOMAIN_STARTS_WITH=mail
In the “certdumper” section of the “docker-compose.override.yml” adjust the points “image” and “environment”.
Restart Mailcow and Traefik
Finally, Traefik must now be restarted and Mailcow re-deployed. The commands must be adapted to the environment and are only exemplary.
user@host:~$sudo -i
host:/mailcow # docker-compose down && docker-compose up -d
host:/mailcow # docker stop traefik && docker start traefik