Thank you @bluepuma77 for the guidance
The final setup to run multiple services (mailu + app) in same server via Traefik is the following (in case someone looking for similar setup):
- first make sure to create a shared docker network :
docker network create traefik-net
- Traefik compose file:
services:
reverse-proxy:
image: traefik:v3.3
ports:
- "80:80"
- "443:443"
- "8080:8080"
- "25:25"
- "465:465"
- "587:587"
- "110:110"
- "995:995"
- "143:143"
- "993:993"
- "4190:4190"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yaml:/etc/traefik/traefik.yaml
- ./dynamic_conf.yaml:/etc/traefik/dynamic_conf.yaml
- ./letsencrypt:/letsencrypt
networks:
- traefik-net
networks:
traefik-net:
external: true
- Mailu front service:
front:
image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-2024.06}
restart: always
env_file: mailu.env
logging:
driver: journald
options:
tag: mailu-front
networks:
- default
- webmail
- traefik-net
volumes:
- "/mailu/certs:/certs"
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-net"
# Dashboard mailu
- "traefik.http.routers.mail.rule=Host(`mail.mydomain.org`)"
- "traefik.http.routers.mail.entrypoints=websecure"
- "traefik.http.routers.mail.tls=true"
- "traefik.http.routers.mail.tls.certresolver=le"
- "traefik.http.services.mail.loadbalancer.server.port=80"
# IMAPS (993)
- "traefik.tcp.routers.mail-imaps.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mail-imaps.entrypoints=imaps"
- "traefik.tcp.routers.mail-imaps.service=mail-imaps"
- "traefik.tcp.services.mail-imaps.loadbalancer.server.port=993"
# IMAPS (143)
- "traefik.tcp.routers.mail-imap.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mail-imap.entrypoints=imap"
- "traefik.tcp.routers.mail-imap.service=mail-imap"
- "traefik.tcp.services.mail-imap.loadbalancer.server.port=143"
# POP3S (995)
- "traefik.tcp.routers.mail-pop3s.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mail-pop3s.entrypoints=pop3s"
- "traefik.tcp.routers.mail-pop3s.service=mail-pop3s"
- "traefik.tcp.services.mail-pop3s.loadbalancer.server.port=995"
# SMTP Relay (25)
- "traefik.tcp.routers.smtp-insecure.rule=HostSNI(`*`)"
- "traefik.tcp.routers.smtp-insecure.entrypoints=smtp-relay"
- "traefik.tcp.routers.smtp-insecure.service=smtp-insecure"
- "traefik.tcp.services.smtp-insecure.loadbalancer.server.port=25"
# SMTPS (465)
- "traefik.tcp.routers.mail-smtps.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mail-smtps.entrypoints=smtps"
- "traefik.tcp.routers.mail-smtps.service=mail-smtps"
- "traefik.tcp.services.mail-smtps.loadbalancer.server.port=465"
# SMTP Submission (587)
- "traefik.tcp.routers.mail-smtp.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mail-smtp.entrypoints=smtp"
- "traefik.tcp.routers.mail-smtp.service=mail-smtp"
- "traefik.tcp.services.mail-smtp.loadbalancer.server.port=587"
# SIEVE (4190)
- "traefik.tcp.routers.mail-sieve.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mail-sieve.entrypoints=sieve"
- "traefik.tcp.routers.mail-sieve.service=mail-sieve"
- "traefik.tcp.services.mail-sieve.loadbalancer.server.port=4190"
- mailu.env:
TLS_FLAVOR=mail-letsencrypt
-
Traefik static configuration (Traefik.yml): UNCHANGED
-
Traefik dynamic configuration (dynamic_conf.yml) (to reverse proxy an app running on Host machine):
http:
routers:
app:
rule: "Host(`app.domain.org`)"
entryPoints:
- websecure
tls:
certResolver: le
service: app
services:
app:
loadBalancer:
servers:
- url: "http://app.domain.org:4443"
passHostHeader: true
If you are wondering why we are exposing the app publicly on port 4443, the reason is we couldn't figure out how to configure Traefik to reach the host network and mailu docker network at same time, we tried network_mode: host
but it complicated things for mailu, to gain time we just exposed the app publicly on port 4443 and made it accessible only by traefik-net network.
you can do that by running docker network inspect traefik-net
, copy subnet address e.g. 172.18.0.0/16
and add the following lines to you nginx conf (or equivalent for other webservers):
server {
# Allow Docker network subnet (traefik-net) and deny the rest
allow 172.1.0.0/16;
deny all;
...
...
...
}