From e128d8e975529485e7533766e43e93d1e4376bbc Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Wed, 5 Dec 2018 21:50:07 +0100 Subject: [PATCH 1/7] Add documentation for usage behind traefik --- docs/reverse.rst | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/reverse.rst b/docs/reverse.rst index ca68fd7f..cd23aad1 100644 --- a/docs/reverse.rst +++ b/docs/reverse.rst @@ -8,6 +8,7 @@ In such a configuration, one would usually run a frontend reverse proxy to serve There are basically three options, from the most to the least recommended one: - have Mailu Web frontend listen locally and use your own Web frontend on top of it +- use ``Traefik`` in another container as central system-reverse-proxy - override Mailu Web frontend configuration - disable Mailu Web frontend completely and use your own @@ -114,6 +115,72 @@ Depending on how you access the front server, you might want to add a ``proxy_re This will stop redirects (301 and 302) sent by the Webmail, nginx front and admin interface from sending you to ``localhost``. +use ``traefik`` in another container as central system-reverse-proxy +-------------------------------------------------------------------- + +``traefik`` is a popular reverse-proxy aimed at containerized systems. As such, many may wish to integrate ``Mailu`` into a system which already uses ``traefik`` as its sole ingress/reverse-proxy. + +As the ``mailu/front`` container uses ``nginx`` not only for ``HTTP`` forwarding, but also for the mail-protocols like ``SMTP``, ``IMAP``, etc, we need to keep this container around even when using another ``HTTP`` reverse-proxy. Furthermore, ``traefik`` is neither able to forward non-HTTP, nor can it easily forward HTTPS-to-HTTPS. This, however, means 3 things: + +- ``mailu/front`` needs to listen internally on ``HTTP`` rather than ``HTTPS`` +- ``mailu/front`` is not exposed to the outside world on ``HTTP`` +- ``mailu/front`` still needs ``SSL`` certificates (here, we assume ``letsencrypt``) for a well-behaved mail service + +This makes the setup with ``traefik`` a bit harder: ``traefik`` saves its certificates in a proprietary ``JSON`` file, which is not readable by the ``nginx`` in the ``front``-container. To solve this, your ``acme.json`` needs to be exposed to the host or a ``docker-volume``. It will then be read by a script in another container, which will dump the certificates as ``PEM`` files, making them readable for ``nginx``. The `front` container will make sure to reload `nginx` whenever these certificates change. + +To set this up, first set ``TLS_FLAVOR=mail`` in your ``.env``. This tells ``mailu/front`` not to try to request certificates using ``letsencrypt``, but to read provided certificates, and use them only for mail-protocols, not for ``HTTP``. +Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``front`` section for port ``…:80`` and ``…:440``. Add the respective traefik labels for your domain/configuration, like + +.. code-block:: yaml + + labels: + - "traefik.enable=true" + - "traefik.port=80" + - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" + +**Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env``** + +If your ``traefik`` is configured to automatically request certificates from ``letsencrypt``, then you’ll have a certificate for ``mail.your.doma.in`` now. However, ``mail.your.doma.in`` might only be the location where you want the ``Mailu`` web-interfaces to live — your mail should be sent/received from ``your.doma.in``, and this is the ``DOMAIN`` in your ``.env``? +To support that use-case, ``traefik`` can request ``SANs`` for your domain. Lets add something like + +.. code-block:: toml + + [acme] + [[acme.domains]] + main = "your.doma.in" # this is the same as $TRAEFIK_DOMAIN! + sans = ["mail.your.doma.in", "webmail.your.doma.in", "smtp.your.doma.in"] + +to your ``traefik.toml``. You might need to clear your ``acme.json``, if a certificate for one of these domains already exists. + +For the last part, you’re still a bit on your own. You need some solution which dumps the certificates in ``acme.json``, so you can include them in the ``mailu/front`` container. One such example is `traefik-certdumper `, which has been adapted for use in Mailu. You can add it to your ``docker-compose.yml`` like: + +.. code-block:: yaml + + certdumper: + restart: always + image: nebukadneza/traefik-certdumper:latest + environment: + # Make sure this is the same as the main=-domain in traefik.toml + # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! + - DOMAIN=$TRAEFIK_DOMAIN + volumes: + - "/data/traefik:/traefik" + - "$ROOT/certs:/output" + + + +assuming you have ``volume-mounted`` your ``acme.json`` put to ``/data/traefik`` on your host. The dumper will then write out ``/data/traefik/ssl/your.doma.in.crt`` and ``/data/traefik/ssl/your.doma.in.key`` whenever ``acme.json`` is updated. Yay! Now let’s mount this to our ``front`` container like: + +.. code-block:: yaml + + volumes: + - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key + - "$ROOT/overrides/nginx:/overrides" + - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem + - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem + + +Note that we still keep the ``$ROOT/certs`` directory-mount there, where ``dhparams.pem`` is going to be placed. Override Mailu configuration ---------------------------- From dc5f5bb023a33d55b1b99a1a4f30407d68390ddf Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Thu, 6 Dec 2018 09:38:28 +0100 Subject: [PATCH 2/7] Traefik configuration examples --- docs/compose/treafik/docker-compose.yml | 145 ++++++++++++++++++++++++ docs/compose/treafik/traefik.toml | 33 ++++++ 2 files changed, 178 insertions(+) create mode 100644 docs/compose/treafik/docker-compose.yml create mode 100644 docs/compose/treafik/traefik.toml diff --git a/docs/compose/treafik/docker-compose.yml b/docs/compose/treafik/docker-compose.yml new file mode 100644 index 00000000..0dc8369f --- /dev/null +++ b/docs/compose/treafik/docker-compose.yml @@ -0,0 +1,145 @@ +version: '2' + +services: + + # This would normally not be here, but where you define your system services + traefik: + image: traefik:alpine + command: --docker + restart: always + ports: + - "80:80" + - "443:443" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + - "/data/traefik/acme.json:/acme.json" + - "/data/traefik/traefik.toml:/traefik.toml" + # This may be needed (plus defining mailu_default external: true) if traefik lives elsewhere + # networks: + # - mailu_default + + certdumper: + restart: always + image: nebukadneza/traefik-certdumper:latest + environment: + # Make sure this is the same as the main=-domain in traefik.toml + # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! + - DOMAIN=$TRAEFIK_DOMAIN + volumes: + - "/data/traefik:/traefik" + - "$ROOT/certs:/output" + + front: + image: mailu/nginx:$VERSION + restart: always + env_file: .env + logging: + driver: $LOG_DRIVER + labels: # Traefik labels for simple reverse-proxying + - "traefik.enable=true" + - "traefik.port=80" + - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" + - "traefik.docker.network=mailu_default" + ports: + - "80" # Let’s not expose 80 or 443 on host, since that’s taken by traefik + - "$BIND_ADDRESS4:110:110" + - "$BIND_ADDRESS4:143:143" + - "$BIND_ADDRESS4:993:993" + - "$BIND_ADDRESS4:995:995" + - "$BIND_ADDRESS4:25:25" + - "$BIND_ADDRESS4:465:465" + - "$BIND_ADDRESS4:587:587" + - "$BIND_ADDRESS6:110:110" + - "$BIND_ADDRESS6:143:143" + - "$BIND_ADDRESS6:993:993" + - "$BIND_ADDRESS6:995:995" + - "$BIND_ADDRESS6:25:25" + - "$BIND_ADDRESS6:465:465" + - "$BIND_ADDRESS6:587:587" + volumes: + - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key + - "$ROOT/overrides/nginx:/overrides" + - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem + - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem + + redis: + image: redis:alpine + restart: always + volumes: + - "$ROOT/redis:/data" + + imap: + image: mailu/dovecot:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/mail:/mail" + - "$ROOT/overrides:/overrides" + depends_on: + - front + + smtp: + image: mailu/postfix:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/overrides:/overrides" + depends_on: + - front + + antispam: + image: mailu/rspamd:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/filter:/var/lib/rspamd" + - "$ROOT/dkim:/dkim" + - "$ROOT/overrides/rspamd:/etc/rspamd/override.d" + depends_on: + - front + + antivirus: + image: mailu/$ANTIVIRUS:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/filter:/data" + + webdav: + image: mailu/$WEBDAV:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/dav:/data" + + admin: + image: mailu/admin:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/data:/data" + - "$ROOT/dkim:/dkim" + depends_on: + - redis + + webmail: + image: "mailu/$WEBMAIL:$VERSION" + restart: always + env_file: .env + volumes: + - "$ROOT/webmail:/data" + depends_on: + - imap + + fetchmail: + image: mailu/fetchmail:$VERSION + restart: always + env_file: .env + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: $SUBNET diff --git a/docs/compose/treafik/traefik.toml b/docs/compose/treafik/traefik.toml new file mode 100644 index 00000000..c09cf42a --- /dev/null +++ b/docs/compose/treafik/traefik.toml @@ -0,0 +1,33 @@ +# This is just boilerplate stuff you probably have in your own config +logLevel = "INFO" +defaultEntryPoints = ["https","http"] + +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + +[docker] +endpoint = "unix:///var/run/docker.sock" +watch = true +exposedByDefault = false + +# Make sure we get acme.json saved, and onHostRule enabled +[acme] +email = "your@mail.tld" +storage = "acme.json" +entryPoint = "https" +onHostRule = true + +[acme.httpChallenge] +entryPoint = "http" + +# This should include all of your mail domains, and main= should be your $TRAEFIK_DOMAIN +[[acme.domains]] + main = "mail.your.doma.in" + sans = ["web.mail.your.doma.in", "smtp.mail.doma.in", "imap.mail.doma.in"] + From 633919e97cb638125ae82626bcb0596ca20a498c Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Wed, 26 Dec 2018 11:42:48 +0100 Subject: [PATCH 3/7] Add docker to dump traefiks certificates to pem This is required since traefik sitting on HTTP is able to grab LetsEncrypt certificates which then need to be injected into the front container. --- optional/traefik-certdumper/.dockerignore | 2 ++ optional/traefik-certdumper/Dockerfile | 8 ++++++ optional/traefik-certdumper/LICENSE | 21 ++++++++++++++++ optional/traefik-certdumper/README.md | 27 ++++++++++++++++++++ optional/traefik-certdumper/run.sh | 30 +++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 optional/traefik-certdumper/.dockerignore create mode 100644 optional/traefik-certdumper/Dockerfile create mode 100644 optional/traefik-certdumper/LICENSE create mode 100644 optional/traefik-certdumper/README.md create mode 100755 optional/traefik-certdumper/run.sh diff --git a/optional/traefik-certdumper/.dockerignore b/optional/traefik-certdumper/.dockerignore new file mode 100644 index 00000000..9b54c5ba --- /dev/null +++ b/optional/traefik-certdumper/.dockerignore @@ -0,0 +1,2 @@ +README.md +Dockerfile diff --git a/optional/traefik-certdumper/Dockerfile b/optional/traefik-certdumper/Dockerfile new file mode 100644 index 00000000..c8a3aa3f --- /dev/null +++ b/optional/traefik-certdumper/Dockerfile @@ -0,0 +1,8 @@ +FROM alpine + +RUN apk --no-cache add inotify-tools jq openssl util-linux bash docker +# while not strictly documented, this script seems to always(?) support previous acme.json versions too +RUN wget https://raw.githubusercontent.com/containous/traefik/master/contrib/scripts/dumpcerts.sh -O dumpcerts.sh + +COPY run.sh / +ENTRYPOINT ["/run.sh"] diff --git a/optional/traefik-certdumper/LICENSE b/optional/traefik-certdumper/LICENSE new file mode 100644 index 00000000..259ccd34 --- /dev/null +++ b/optional/traefik-certdumper/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Sven Dowideit + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/optional/traefik-certdumper/README.md b/optional/traefik-certdumper/README.md new file mode 100644 index 00000000..f5434f62 --- /dev/null +++ b/optional/traefik-certdumper/README.md @@ -0,0 +1,27 @@ +# Single-domain traefik-certdumper for mailu + +This is based on the work by Sven Dowideit on https://github.com/SvenDowideit/traefik-certdumper + +## Fork? +This is a slight modification that is less flexible, but is adapted to the +usecase in mailu. If you wish to deploy mailu behind a traefik, you face many +problems. One of these is that you need to get the certificates into mailu in a +very defined manner. This will copy the certificate for the **Main:**-domain +given in the DOMAIN-environment onto `output`. + +If your output happens to be mailu-front-`/certs`, the certificate-watcher in +the front-container will catch it and reload nginx. This works for mailu +`TLS_FLAVOR=[mail, cert]` + + +``` + certdumper: + restart: always + image: Mailu/traefik-certdumper:$VERSION + environment: + - DOMAIN=$DOMAIN + volumes: + # your traefik data-volume is probably declared outside of the mailu composefile + - /data/traefik:/traefik + - $ROOT/certs/:/output/ +``` diff --git a/optional/traefik-certdumper/run.sh b/optional/traefik-certdumper/run.sh new file mode 100755 index 00000000..2f73eaf7 --- /dev/null +++ b/optional/traefik-certdumper/run.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +function dump() { + echo "$(date) Dumping certificates" + bash dumpcerts.sh /traefik/acme.json /tmp/work/ + + for crt_file in $(ls /tmp/work/certs/*); do + pem_file=$(echo $crt_file | sed 's/certs/pem/g' | sed 's/.crt/-public.pem/g') + echo "openssl x509 -inform PEM -in $crt_file > $pem_file" + openssl x509 -inform PEM -in $crt_file > $pem_file + done + for key_file in $(ls /tmp/work/private/*); do + pem_file=$(echo $key_file | sed 's/private/pem/g' | sed 's/.key/-private.pem/g') + echo "openssl rsa -in $key_file -text > $pem_file" + openssl rsa -in $key_file -text > $pem_file + done + + echo "$(date) Copying certificates" + cp -v /tmp/work/pem/${DOMAIN}-private.pem /output/key.pem + cp -v /tmp/work/pem/${DOMAIN}-public.pem /output/cert.pem +} + +mkdir -p /tmp/work/pem /tmp/work/certs +# run once on start to make sure we have any old certs +dump + +while true; do + inotifywait -e modify /traefik/acme.json && \ + dump +done From d6ba39b6a9736b9c972781caf7ec6888856713cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 16:49:37 +0200 Subject: [PATCH 4/7] Traefik docs improvements: - Removed code tages to increase readability - Some extra line-breaks for source readability - Fix link to new mailu/traefik-certdumper container - dhparams is no longer stored in /certs - Use a proper "note" box - Fix typo in docs/compose/traefik directory name - Include links to example config files - Fix toml lexer build warning --- .../{treafik => traefik}/docker-compose.yml | 4 +- .../compose/{treafik => traefik}/traefik.toml | 0 docs/reverse.rst | 49 ++++++++++++------- 3 files changed, 32 insertions(+), 21 deletions(-) rename docs/compose/{treafik => traefik}/docker-compose.yml (93%) rename docs/compose/{treafik => traefik}/traefik.toml (100%) diff --git a/docs/compose/treafik/docker-compose.yml b/docs/compose/traefik/docker-compose.yml similarity index 93% rename from docs/compose/treafik/docker-compose.yml rename to docs/compose/traefik/docker-compose.yml index 0dc8369f..607fcaf1 100644 --- a/docs/compose/treafik/docker-compose.yml +++ b/docs/compose/traefik/docker-compose.yml @@ -20,7 +20,7 @@ services: certdumper: restart: always - image: nebukadneza/traefik-certdumper:latest + image: mailu/traefik-certdumper:$VERSION environment: # Make sure this is the same as the main=-domain in traefik.toml # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! @@ -41,7 +41,6 @@ services: - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" - "traefik.docker.network=mailu_default" ports: - - "80" # Let’s not expose 80 or 443 on host, since that’s taken by traefik - "$BIND_ADDRESS4:110:110" - "$BIND_ADDRESS4:143:143" - "$BIND_ADDRESS4:993:993" @@ -57,7 +56,6 @@ services: - "$BIND_ADDRESS6:465:465" - "$BIND_ADDRESS6:587:587" volumes: - - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key - "$ROOT/overrides/nginx:/overrides" - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem diff --git a/docs/compose/treafik/traefik.toml b/docs/compose/traefik/traefik.toml similarity index 100% rename from docs/compose/treafik/traefik.toml rename to docs/compose/traefik/traefik.toml diff --git a/docs/reverse.rst b/docs/reverse.rst index cd23aad1..5f64b8f3 100644 --- a/docs/reverse.rst +++ b/docs/reverse.rst @@ -115,21 +115,28 @@ Depending on how you access the front server, you might want to add a ``proxy_re This will stop redirects (301 and 302) sent by the Webmail, nginx front and admin interface from sending you to ``localhost``. -use ``traefik`` in another container as central system-reverse-proxy +Use Traefik in another container as central system-reverse-proxy -------------------------------------------------------------------- -``traefik`` is a popular reverse-proxy aimed at containerized systems. As such, many may wish to integrate ``Mailu`` into a system which already uses ``traefik`` as its sole ingress/reverse-proxy. +`Traefik`_ is a popular reverse-proxy aimed at containerized systems. +As such, many may wish to integrate Mailu into a system which already uses Traefik as its sole ingress/reverse-proxy. -As the ``mailu/front`` container uses ``nginx`` not only for ``HTTP`` forwarding, but also for the mail-protocols like ``SMTP``, ``IMAP``, etc, we need to keep this container around even when using another ``HTTP`` reverse-proxy. Furthermore, ``traefik`` is neither able to forward non-HTTP, nor can it easily forward HTTPS-to-HTTPS. This, however, means 3 things: +As the ``mailu/front`` container uses Nginx not only for ``HTTP`` forwarding, but also for the mail-protocols like ``SMTP``, ``IMAP``, etc, we need to keep this +container around even when using another ``HTTP`` reverse-proxy. Furthermore, Traefik is neither able to forward non-HTTP, nor can it easily forward HTTPS-to-HTTPS. +This, however, means 3 things: - ``mailu/front`` needs to listen internally on ``HTTP`` rather than ``HTTPS`` - ``mailu/front`` is not exposed to the outside world on ``HTTP`` - ``mailu/front`` still needs ``SSL`` certificates (here, we assume ``letsencrypt``) for a well-behaved mail service -This makes the setup with ``traefik`` a bit harder: ``traefik`` saves its certificates in a proprietary ``JSON`` file, which is not readable by the ``nginx`` in the ``front``-container. To solve this, your ``acme.json`` needs to be exposed to the host or a ``docker-volume``. It will then be read by a script in another container, which will dump the certificates as ``PEM`` files, making them readable for ``nginx``. The `front` container will make sure to reload `nginx` whenever these certificates change. +This makes the setup with Traefik a bit harder: Traefik saves its certificates in a proprietary *JSON* file, which is not readable by Nginx in the ``front``-container. +To solve this, your ``acme.json`` needs to be exposed to the host or a ``docker-volume``. It will then be read by a script in another container, +which will dump the certificates as ``PEM`` files, readable for Nginx. The ``front`` container will automatically reload Nginx whenever these certificates change. -To set this up, first set ``TLS_FLAVOR=mail`` in your ``.env``. This tells ``mailu/front`` not to try to request certificates using ``letsencrypt``, but to read provided certificates, and use them only for mail-protocols, not for ``HTTP``. -Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``front`` section for port ``…:80`` and ``…:440``. Add the respective traefik labels for your domain/configuration, like +To set this up, first set ``TLS_FLAVOR=mail`` in your ``.env``. This tells ``mailu/front`` not to try to request certificates using ``letsencrypt``, +but to read provided certificates, and use them only for mail-protocols, not for ``HTTP``. +Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``front`` section for port ``…:80`` and ``…:440``. +Add the respective Traefik labels for your domain/configuration, like .. code-block:: yaml @@ -138,12 +145,14 @@ Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``fr - "traefik.port=80" - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" -**Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env``** +.. note:: Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env`` -If your ``traefik`` is configured to automatically request certificates from ``letsencrypt``, then you’ll have a certificate for ``mail.your.doma.in`` now. However, ``mail.your.doma.in`` might only be the location where you want the ``Mailu`` web-interfaces to live — your mail should be sent/received from ``your.doma.in``, and this is the ``DOMAIN`` in your ``.env``? -To support that use-case, ``traefik`` can request ``SANs`` for your domain. Lets add something like +If your Traefik is configured to automatically request certificates from *letsencrypt*, then you’ll have a certificate for ``mail.your.doma.in`` now. However, +``mail.your.doma.in`` might only be the location where you want the Mailu web-interfaces to live — your mail should be sent/received from ``your.doma.in``, +and this is the ``DOMAIN`` in your ``.env``? +To support that use-case, Traefik can request ``SANs`` for your domain. Lets add something like -.. code-block:: toml +.. code-block:: guess [acme] [[acme.domains]] @@ -152,13 +161,14 @@ To support that use-case, ``traefik`` can request ``SANs`` for your domain. Lets to your ``traefik.toml``. You might need to clear your ``acme.json``, if a certificate for one of these domains already exists. -For the last part, you’re still a bit on your own. You need some solution which dumps the certificates in ``acme.json``, so you can include them in the ``mailu/front`` container. One such example is `traefik-certdumper `, which has been adapted for use in Mailu. You can add it to your ``docker-compose.yml`` like: +You will need some solution which dumps the certificates in ``acme.json``, so you can include them in the ``mailu/front`` container. +One such example is ``mailu/traefik-certdumper``, which has been adapted for use in Mailu. You can add it to your ``docker-compose.yml`` like: .. code-block:: yaml certdumper: restart: always - image: nebukadneza/traefik-certdumper:latest + image: mailu/traefik-certdumper:$VERSION environment: # Make sure this is the same as the main=-domain in traefik.toml # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! @@ -169,23 +179,23 @@ For the last part, you’re still a bit on your own. You need some solution whic -assuming you have ``volume-mounted`` your ``acme.json`` put to ``/data/traefik`` on your host. The dumper will then write out ``/data/traefik/ssl/your.doma.in.crt`` and ``/data/traefik/ssl/your.doma.in.key`` whenever ``acme.json`` is updated. Yay! Now let’s mount this to our ``front`` container like: +Assuming you have ``volume-mounted`` your ``acme.json`` put to ``/data/traefik`` on your host. The dumper will then write out ``/data/traefik/ssl/your.doma.in.crt`` +and ``/data/traefik/ssl/your.doma.in.key`` whenever ``acme.json`` is updated. Yay! Now let’s mount this to our ``front`` container like: .. code-block:: yaml volumes: - - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key - "$ROOT/overrides/nginx:/overrides" - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem - -Note that we still keep the ``$ROOT/certs`` directory-mount there, where ``dhparams.pem`` is going to be placed. +.. _`Traefik`: https://traefik.io/ Override Mailu configuration ---------------------------- -If you do not have the resources for running a separate reverse proxy, you could override Mailu reverse proxy configuration by using a Docker volume. Simply store your configuration file (Nginx format), in ``/mailu/nginx.conf`` for instance. +If you do not have the resources for running a separate reverse proxy, you could override Mailu reverse proxy configuration by using a Docker volume. +Simply store your configuration file (Nginx format), in ``/mailu/nginx.conf`` for instance. Then modify your ``docker-compose.yml`` file and change the ``front`` section to add a mount: @@ -202,7 +212,10 @@ Then modify your ``docker-compose.yml`` file and change the ``front`` section to - "$ROOT/certs:/certs" - "$ROOT/nginx.conf:/etc/nginx/nginx.conf" -You can use our default configuration file as a sane base for your configuration. +You can also download the example configuration files: + +- :download:`compose/traefik/docker-compose.yml` +- :download:`compose/traefik/traefik.toml` Disable completely Mailu reverse proxy -------------------------------------- From fd23e02aaa25d556403d05f2280a9b16f2a04fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 16:55:18 +0200 Subject: [PATCH 5/7] Use alpine versioned and defin volumes --- optional/traefik-certdumper/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/optional/traefik-certdumper/Dockerfile b/optional/traefik-certdumper/Dockerfile index c8a3aa3f..92e5e900 100644 --- a/optional/traefik-certdumper/Dockerfile +++ b/optional/traefik-certdumper/Dockerfile @@ -1,8 +1,11 @@ -FROM alpine +FROM alpine:3.8 RUN apk --no-cache add inotify-tools jq openssl util-linux bash docker # while not strictly documented, this script seems to always(?) support previous acme.json versions too RUN wget https://raw.githubusercontent.com/containous/traefik/master/contrib/scripts/dumpcerts.sh -O dumpcerts.sh +VOLUME ["/traefik"] +VOLUME ["/output"] + COPY run.sh / ENTRYPOINT ["/run.sh"] From 7c7b52d935fbfbd0e90d82c963fa4a70d906045e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 17:06:52 +0200 Subject: [PATCH 6/7] Include certdumper in autobuild --- tests/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/build.yml b/tests/build.yml index 0d89c5b8..4f6e33de 100644 --- a/tests/build.yml +++ b/tests/build.yml @@ -30,6 +30,10 @@ services: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}radicale:${MAILU_VERSION:-local} build: ../optional/radicale + traefik-certdumper: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}traefik-certdumper:${MAILU_VERSION:-local} + build: ../optional/traefik-certdumper + admin: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}admin:${MAILU_VERSION:-local} build: ../core/admin From a5b96553aac0919fda68b64ef2dab7d2f48a4767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 18:47:12 +0200 Subject: [PATCH 7/7] Check for dumpcerts.sh return status code --- optional/traefik-certdumper/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optional/traefik-certdumper/run.sh b/optional/traefik-certdumper/run.sh index 2f73eaf7..78d20a84 100755 --- a/optional/traefik-certdumper/run.sh +++ b/optional/traefik-certdumper/run.sh @@ -2,7 +2,7 @@ function dump() { echo "$(date) Dumping certificates" - bash dumpcerts.sh /traefik/acme.json /tmp/work/ + bash dumpcerts.sh /traefik/acme.json /tmp/work/ || return for crt_file in $(ls /tmp/work/certs/*); do pem_file=$(echo $crt_file | sed 's/certs/pem/g' | sed 's/.crt/-public.pem/g')