mirror of
https://github.com/Mailu/Mailu.git
synced 2025-01-18 03:21:36 +02:00
doc
This commit is contained in:
parent
f3cd401450
commit
b7e7f0d8b6
@ -1,144 +0,0 @@
|
||||
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: 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!
|
||||
- DOMAIN=$TRAEFIK_DOMAIN
|
||||
# Set TRAEFIK_VERSION to v2 in your .env if you're using Traefik v2
|
||||
- TRAEFIK_VERSION=${TRAEFIK_VERSION:-v1}
|
||||
volumes:
|
||||
- "/data/traefik:/traefik"
|
||||
- "$ROOT/certs:/output"
|
||||
|
||||
front:
|
||||
image: mailu/nginx:$VERSION
|
||||
restart: always
|
||||
env_file: .env
|
||||
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:
|
||||
- "$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/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"
|
||||
- "$ROOT/overrides/$WEBMAIL:/overrides:ro"
|
||||
depends_on:
|
||||
- imap
|
||||
|
||||
fetchmail:
|
||||
image: mailu/fetchmail:$VERSION
|
||||
restart: always
|
||||
env_file: .env
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: $SUBNET
|
@ -1,33 +0,0 @@
|
||||
# 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.example.com"
|
||||
sans = ["web.mail.example.com", "smtp.mail.example.com", "imap.mail.example.com"]
|
||||
|
174
docs/reverse.rst
174
docs/reverse.rst
@ -162,81 +162,127 @@ This will stop redirects (301 and 302) sent by the Webmail, nginx front and admi
|
||||
Traefik as 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.
|
||||
.. code-block:: yaml
|
||||
reverse-proxy:
|
||||
# The official v2 Traefik docker image
|
||||
image: traefik:v2.10
|
||||
# Enables the web UI and tells Traefik to listen to docker
|
||||
command:
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--providers.docker.allowEmptyServices=true"
|
||||
- "--entrypoints.web.address=:http"
|
||||
- "--entrypoints.websecure.address=:https"
|
||||
- "--entrypoints.smtp.address=:smtp"
|
||||
- "--entrypoints.submission.address=:submission"
|
||||
- "--entrypoints.submissions.address=:submissions"
|
||||
- "--entrypoints.imap.address=:imap"
|
||||
- "--entrypoints.imaps.address=:imaps"
|
||||
- "--entrypoints.pop3.address=:pop3"
|
||||
- "--entrypoints.pop3s.address=:pop3s"
|
||||
- "--entrypoints.sieve.address=:sieve"
|
||||
# - "--api.insecure=true"
|
||||
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
|
||||
- "--certificatesresolvers.myresolver.acme.email=test@example.com"
|
||||
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
|
||||
- "--log.level=DEBUG"
|
||||
ports:
|
||||
# The HTTP port
|
||||
- "25:25"
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "465:465"
|
||||
- "587:587"
|
||||
- "993:993"
|
||||
- "995:995"
|
||||
- "110:110"
|
||||
- "143:143"
|
||||
- "4190:4190"
|
||||
# The Web UI (enabled by --api.insecure=true)
|
||||
#- "8080:8080"
|
||||
volumes:
|
||||
# So that Traefik can listen to the Docker events
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
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 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 ``…:443``.
|
||||
Add the respective Traefik labels for your domain/configuration, like
|
||||
and then for front:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
labels:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.port=80"
|
||||
- "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN"
|
||||
|
||||
.. note:: Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env``
|
||||
# the second part is important to ensure Mailu can get certificates for the main FQDN
|
||||
- "traefik.http.routers.web.rule=Host(`fqdn.example.com`) || Path(`/.well-known/acme-challenge/`)"
|
||||
- "traefik.http.routers.web.entrypoints=web"
|
||||
- "traefik.http.services.web.loadbalancer.server.port=80"
|
||||
|
||||
If your Traefik is configured to automatically request certificates from *letsencrypt*, then you’ll have a certificate
|
||||
for ``mail.your.example.com`` now. However, ``mail.your.example.com`` might only be the location where you want the Mailu web-interfaces
|
||||
to live — your mail should be sent/received from ``your.example.com``, and this is the ``DOMAIN`` in your ``.env``?
|
||||
To support that use-case, Traefik can request ``SANs`` for your domain. The configuration for this will depend on your Traefik version.
|
||||
# add other FQDNS here too
|
||||
- "traefik.tcp.routers.websecure.rule=HostSNI(`fqdn.example.com`) || HostSNI(`autoconfig.example.com`) || HostSNI(`mta-sts.example.com`)"
|
||||
- "traefik.tcp.routers.websecure.entrypoints=websecure"
|
||||
- "traefik.tcp.routers.websecure.tls.passthrough=true"
|
||||
- "traefik.tcp.routers.websecure.service=websecure"
|
||||
- "traefik.tcp.services.websecure.loadbalancer.server.port=443"
|
||||
- "traefik.tcp.services.websecure.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
Mailu must also be configured with the information what header is used by the reverse proxy for passing the remote
|
||||
client IP. This is configured in mailu.env:
|
||||
- "traefik.tcp.routers.smtp.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.smtp.entrypoints=smtp"
|
||||
- "traefik.tcp.routers.smtp.service=smtp"
|
||||
- "traefik.tcp.services.smtp.loadbalancer.server.port=25"
|
||||
- "traefik.tcp.services.smtp.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
- "traefik.tcp.routers.submission.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.submission.entrypoints=submission"
|
||||
- "traefik.tcp.routers.submission.service=submission"
|
||||
- "traefik.tcp.services.submission.loadbalancer.server.port=587"
|
||||
- "traefik.tcp.services.submission.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
- "traefik.tcp.routers.submissions.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.submissions.entrypoints=submissions"
|
||||
- "traefik.tcp.routers.submissions.service=submissions"
|
||||
- "traefik.tcp.services.submissions.loadbalancer.server.port=465"
|
||||
- "traefik.tcp.services.submissions.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
- "traefik.tcp.routers.imap.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.imap.entrypoints=imap"
|
||||
- "traefik.tcp.routers.imap.service=imap"
|
||||
- "traefik.tcp.services.imap.loadbalancer.server.port=143"
|
||||
- "traefik.tcp.services.imap.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
- "traefik.tcp.routers.imaps.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.imaps.entrypoints=imaps"
|
||||
- "traefik.tcp.routers.imaps.service=imaps"
|
||||
- "traefik.tcp.services.imaps.loadbalancer.server.port=993"
|
||||
- "traefik.tcp.services.imaps.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
- "traefik.tcp.routers.pop3.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.pop3.entrypoints=pop3"
|
||||
- "traefik.tcp.routers.pop3.service=pop3"
|
||||
- "traefik.tcp.services.pop3.loadbalancer.server.port=110"
|
||||
- "traefik.tcp.services.pop3.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
- "traefik.tcp.routers.pop3s.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.pop3s.entrypoints=pop3s"
|
||||
- "traefik.tcp.routers.pop3s.service=pop3s"
|
||||
- "traefik.tcp.services.pop3s.loadbalancer.server.port=995"
|
||||
- "traefik.tcp.services.pop3s.loadbalancer.proxyProtocol.version=2"
|
||||
|
||||
- "traefik.tcp.routers.sieve.rule=HostSNI(`*`)"
|
||||
- "traefik.tcp.routers.sieve.entrypoints=sieve"
|
||||
- "traefik.tcp.routers.sieve.service=sieve"
|
||||
- "traefik.tcp.services.sieve.loadbalancer.server.port=4190"
|
||||
- "traefik.tcp.services.sieve.loadbalancer.proxyProtocol.version=2"
|
||||
healthcheck:
|
||||
test: ['NONE']
|
||||
|
||||
in mailu.env:
|
||||
|
||||
.. code-block:: docker
|
||||
|
||||
#mailu.env file
|
||||
REAL_IP_HEADER=X-Real-Ip
|
||||
REAL_IP_FROM=x.x.x.x,y.y.y.y.y
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
|
||||
For more information see the :ref:`configuration reference <reverse_proxy_headers>` for more information.
|
||||
|
||||
Traefik 2.x using labels configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Add the appropriate labels for your domain(s) to the ``front`` container in ``docker-compose.yml``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
services:
|
||||
front:
|
||||
labels:
|
||||
# Enable TLS
|
||||
- "traefik.http.routers.mailu-secure.tls"
|
||||
# Your main domain
|
||||
- "traefik.http.routers.mailu-secure.tls.domains[0].main=your.example.com"
|
||||
# Optional SANs for your main domain
|
||||
- "traefik.http.routers.mailu-secure.tls.domains[0].sans=mail.your.example.com,webmail.your.example.com,smtp.your.example.com"
|
||||
# Optionally add other domains
|
||||
- "traefik.http.routers.mailu-secure.tls.domains[1].main=mail.other.example.com"
|
||||
- "traefik.http.routers.mailu-secure.tls.domains[1].sans=mail2.other.example.com,mail3.other.example.com"
|
||||
# Your ACME certificate resolver
|
||||
- "traefik.http.routers.mailu-secure.tls.certResolver=foo"
|
||||
|
||||
Of course, be sure to define the Certificate Resolver ``foo`` in the static configuration as well.
|
||||
|
||||
Alternatively, you can define SANs in the Traefik static configuration using routers, or in the static configuration using entrypoints.
|
||||
Refer to the Traefik documentation for more details.
|
||||
REAL_IP_FROM=192.168.203.0/24
|
||||
PROXY_PROTOCOL=all-but-http
|
||||
TRAEFIK_VERSION=v2
|
||||
TLS_FLAVOR=mail-letsencrypt
|
||||
WEBROOT_REDIRECT=/sso/login
|
||||
|
||||
.. _`Traefik`: https://traefik.io/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user