From c8f89709248d651ca465185a13fd6fed3941d295 Mon Sep 17 00:00:00 2001 From: Andrew Savinykh <658865+AndrewSav@users.noreply.github.com> Date: Wed, 16 Sep 2026 21:02:38 +0000 Subject: [PATCH] Document Traefik 3 configuration --- README.md | 81 +++++++++++++++--------------------------------------- sample.env | 2 +- 2 files changed, 23 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index d179839b..886703a5 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Thank you very much. - [A converted example](#a-converted-example) - [Checking the result](#checking-the-result) - [Clearing the rspamd hyperscan cache after an rspamd upgrade](#clearing-the-rspamd-hyperscan-cache-after-an-rspamd-upgrade) + - [Migration from Traefik 2 to 3](#migration-from-traefik-2-to-3) - [Migration from Traefik 1 to 2](#migration-from-traefik-1-to-2) - [Migration from 1.0 to 1.1](#migration-from-10-to-11) - [Migration from hardware/mailserver to mailserver2/mailserver](#migration-from-hardwaremailserver-to-mailserver2mailserver) @@ -264,12 +265,11 @@ At first launch, the container takes few minutes to generate SSL certificates (i | Service | URI | | --------------------- | -------------------------------- | -| **Traefik dashboard** | https://mail.domain.tld/ | | **Rspamd dashboard** | https://spam.domain.tld/ | | **Administration** | https://postfixadmin.domain.tld/ | | **Webmail** | https://webmail.domain.tld/ | -Traefik dashboard use a basic authentication (user:admin, password:12345), the password can be encoded in MD5, SHA1 and BCrypt. You can use [htpasswd ](https://httpd.apache.org/docs/2.4/programs/htpasswd.html) to generate those ones. Users can be specified directly in the `traefik.toml` file. Rspamd dashboard use the password defined in your `docker-compose.yml`. +The Traefik dashboard is not exposed by this configuration, see the [Traefik documentation](https://doc.traefik.io/traefik/operations/dashboard/) to enable it. Rspamd dashboard use the password defined in your `docker-compose.yml`. You can check the startup logs with this command: @@ -495,7 +495,7 @@ You can use this variable to allow other local containers to relay via the mails #### Let's Encrypt certificates generated by Traefik -To use Let's Encrypt certificates generated by Traefik, mount a new docker volume like this: +To use Let's Encrypt certificates generated by Traefik, mount the Traefik `acme` folder in the mailserver container: ```yml mailserver: @@ -505,80 +505,37 @@ mailserver: ... ``` -The startup script read the `acme.json`* file generated by Traefik and split into pem files all appropriate certificates (CN = mail.domain.tld). +:bulb: On a host running SELinux in enforcing mode, append `:z` to that mount, so that both containers are allowed to access the folder. -:bulb: *Compatible with both Traefik `>=1.5.0` and `1.6+` ACME json format, with **SAN** and **wildcard** certificates support. +The startup script reads `acme.json`, extracts the certificate issued for your mailserver FQDN (default: `mail.domain.tld`) and reloads Postfix and Dovecot every time Traefik renews it. A wildcard certificate for your domain (`*.domain.tld`) is used as well, when `acme.json` contains one. -``` -docker logs -f mailserver - -[INFO] Search for SSL certificates generated by Traefik -[INFO] acme.json found with ACME v2 format, dumping into pem files -[INFO] Let's encrypt live directory found -[INFO] Using /etc/letsencrypt/live/mail.domain.tld folder -``` - -Don't forget to add a new Traefik frontend rule somewhere in your docker-compose.yml to generate a certificate for your mailserver FQDN (default: mail.domain.tld) subdomain. +Traefik only requests certificates for the domains it serves, so your FQDN has to appear in the labels of one of your containers. In [docker-compose.sample.yml](docker-compose.sample.yml) the Rspamd router does this, by requesting a certificate whose main domain is the mailserver FQDN: ```yml -# docker-compose.yml - labels: - - traefik.frontend.rule=Host:mail.${DOMAIN} + - "traefik.http.routers.spam.rule=Host(`spam.${MAILSERVER_DOMAIN}`)" + - "traefik.http.routers.spam.tls.certresolver=letsencrypt" + - "traefik.http.routers.spam.tls.domains[0].main=${MAILSERVER_HOSTNAME}.${MAILSERVER_DOMAIN}" + - "traefik.http.routers.spam.tls.domains[0].sans=spam.${MAILSERVER_DOMAIN}" ``` -Alternatively, you can specify your domains in the `traefik.toml` to generate a SAN certificate: +:warning: A wildcard certificate can only be issued through a `DNS-01` challenge. To use one, replace the `tlsChallenge` section of `traefik.toml` with your [DNS provider](https://doc.traefik.io/traefik/https/acme/#dnschallenge): ```toml -[acme] -onHostRule = false - -[[acme.domains]] -main = "domain.tld" -sans = ["mail.domain.tld", "spam.domain.tld", "postfixadmin.domain.tld", "webmail.domain.tld"] -``` - -Or a wildcard certificate: - -:warning: ACME wildcard certificates can only be generated thanks to a `DNS-01` challenge. - -```toml -[acme] -onHostRule = false - -# https://docs.traefik.io/v1.6/configuration/acme/#dnschallenge -[acme.dnsChallenge] +# traefik.toml +[certificatesResolvers.letsencrypt.acme.dnsChallenge] provider = "your_dns_provider" -delayBeforeCheck = 0 - -[[acme.domains]] -main = "*.domain.tld" ``` -If the startup script does not find the appropriate SSL certificate and private key, look at the Traefik logs to see what's going on. +If the mailserver does not find a certificate, it logs: ``` -docker logs -f mailserver - -[INFO] Search for SSL certificates generated by Traefik -[INFO] ... -[INFO] ... -[INFO] acme.json found with ACME v2 format, dumping into pem files [ERROR] The certificate for mail.domain.tld or the private key was not found ! -[INFO] Don't forget to add a new traefik frontend rule to generate a certificate for mail.domain.tld subdomain -[INFO] Look /mnt/docker/traefik/acme/dump.log and 'docker logs traefik' for more information ``` -```toml -# traefik.toml - -[acme] -acmeLogging = true -``` +Check that Traefik actually issued it with `docker logs traefik`, after setting `level = "DEBUG"` in the `[log]` section of `traefik.toml`. When the extraction itself fails, its output is kept in `/mnt/docker/mail/ssl/acme_dump.log`. -``` -docker-compose restart traefik && docker logs -f traefik -``` +:bulb: `acme.json` has the same format in Traefik 2 and 3. Files written by Traefik 1.x are still supported, their configuration is described in the [Traefik 1.7 documentation](https://doc.traefik.io/traefik/v1.7/configuration/acme/). #### Custom certificates @@ -1325,6 +1282,12 @@ docker compose exec mailserver ls /var/log/mail.err

Back to table of contents :arrow_up_small:

+### Migration from Traefik 2 to 3 + +Migrating from Traefik 2 to 3 only changes the version of the Traefik image. The labels in [docker-compose.sample.yml](docker-compose.sample.yml), [traefik.sample.toml](traefik.sample.toml) and [file.sample.toml](file.sample.toml) are accepted by Traefik 3 unchanged, and `acme.json` keeps the same format, so your existing certificates are kept. If you added routers of your own, check the [Traefik v3 migration guide](https://doc.traefik.io/traefik/migrate/v2-to-v3/): the router rule syntax changed in v3. + +

Back to table of contents :arrow_up_small:

+ ### Migration from Traefik 1 to 2 Migrating from traefik 1 to 2 does not change any mailserver images that are used, only the traefik image version. You do need to update traefik labels on all containers as per [docker-compose.sample.yml](docker-compose.sample.yml). When you do this, either delete your acme.json and let traefik request the new certificate, or use the [tool](https://github.com/traefik/traefik-migration-tool) to convert from v1 to v2. diff --git a/sample.env b/sample.env index 81595cb5..87893bfb 100644 --- a/sample.env +++ b/sample.env @@ -30,7 +30,7 @@ POSTFIXADMIN_DOCKER_TAG=3.2.4 RAINLOOP_DOCKER_TAG=1.14.0 -TRAEFIK_DOCKER_TAG=2.2.11 +TRAEFIK_DOCKER_TAG=3.7 # Docker volumes parent folder VOLUMES_ROOT_PATH=/mnt/docker