-
Hey y'all so I'm trying to setup my own little mail server and I'm getting into some hurdles. docker-compose.yml services:
traefik:
container_name: traefik
image: traefik:v3.0
restart: always
networks:
proxy:
ipv4_address: 172.19.0.2
ports:
- 80:80
- 443:443
- 25:25
- 587:587
- 993:993
- 4190:4190
volumes:
- /etc/localtime:/etc/localtime:ro
- ./traefik:/etc/traefik
- acme:/etc/certs
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- --log.level=DEBUG
- --certificatesresolvers.leresolver.acme.tlschallenge=true
- --certificatesresolvers.leresolver.acme.email=totalyvalidemail@email.email
- --certificatesresolvers.leresolver.acme.storage=/etc/certs/acme.json
- --entrypoints.http.address=:80
- --entrypoints.http.http.redirections.entrypoint.to=https
- --entrypoints.http.http.redirections.entrypoint.scheme=https
- --entrypoints.https.address=:443
- --entrypoints.https.http.tls.certresolver=leresolver
- --entrypoints.smtp.address=:25
- --entrypoints.smtp.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --entrypoints.smtps.address=:587
- --entrypoints.smtps.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --entrypoints.imaps.address=:993
- --entrypoints.imaps.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --entrypoints.managed-sieve.address=:4190
- --entrypoints.managed-sieve.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --providers.docker=true
- --providers.docker.exposedByDefault=false
- --providers.docker.network=proxy
- --providers.file.filename=/etc/traefik/traefik-dynamic.yml
- --providers.file.watch=true
traefik-certs-dumper:
container_name: traefik-certs-dumper
image: ghcr.io/kereis/traefik-certs-dumper:latest
restart: unless-stopped
depends_on:
- traefik
volumes:
- /etc/localtime:/etc/localtime:ro
- acme:/traefik:ro
- certs:/output
mailserver:
container_name: stalwart
image: stalwartlabs/mail-server:latest
restart: unless-stopped
hostname: mail.sub.domain.tld
networks:
proxy:
ipv4_address: 172.19.0.5
volumes:
- /etc/localtime:/etc/localtime:ro
- ./stalwart-mail:/opt/stalwart-mail
- certs:/data/certs:ro
labels:
- traefik.enable=true
- traefik.http.routers.mailserver.rule=Host(`mail.sub.differentdomain.tld`) || Host(`mail.sub.domain.tld`) || Host(`autodiscover.sub.domain.tld`) || Host(`autoconfig.sub.domain.tld`) || Host(`mta-sts.sub.domain.tld`)
- traefik.http.routers.mailserver.entrypoints=https
- traefik.http.routers.mailserver.service=mailserver
- traefik.http.services.mailserver.loadbalancer.server.port=8080
- 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.jmap.rule=HostSNI(`*`)
- traefik.tcp.routers.jmap.tls.passthrough=true
- traefik.tcp.routers.jmap.entrypoints=https
- traefik.tcp.routers.jmap.service=jmap
- traefik.tcp.services.jmap.loadbalancer.server.port=443
- traefik.tcp.services.jmap.loadbalancer.proxyProtocol.version=2
- traefik.tcp.routers.smtps.rule=HostSNI(`*`)
- traefik.tcp.routers.smtps.tls.passthrough=true
- traefik.tcp.routers.smtps.entrypoints=smtps
- traefik.tcp.routers.smtps.service=smtps
- traefik.tcp.services.smtps.loadbalancer.server.port=587
- traefik.tcp.services.smtps.loadbalancer.proxyProtocol.version=2
- traefik.tcp.routers.imaps.rule=HostSNI(`*`)
- traefik.tcp.routers.imaps.tls.passthrough=true
- 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.managed-sieve.rule=HostSNI(`*`)
- traefik.tcp.routers.managed-sieve.entrypoints=managed-sieve
- traefik.tcp.routers.managed-sieve.service=managed-sieve
- traefik.tcp.services.managed-sieve.loadbalancer.server.port=4190
- traefik.tcp.services.managed-sieve.loadbalancer.proxyProtocol.version=2
roundcubemail:
container_name: roundcube
image: roundcube/roundcubemail:latest
restart: unless-stopped
networks:
proxy:
depends_on:
- mailserver
volumes:
- ./roundcube/www:/var/www/html
- ./roundcube/db/sqlite:/var/roundcube/db
- ./roundcube/config:/var/roundcube/config
environment:
ROUNDCUBEMAIL_DB_TYPE: sqlite
ROUNDCUBEMAIL_SKIN: elastic
ROUNDCUBEMAIL_DEFAULT_HOST: tls://mail.sub.domain.tld
ROUNDCUBEMAIL_DEFAULT_PORT: 993
ROUNDCUBEMAIL_SMTP_SERVER: tls://mail.sub.domain.tld
ROUNDCUBEMAIL_PLUGINS: archive,zipdownload,database_attachments,managesieve
ROUNDCUBEMAIL_INSTALL_PLUGINS: 1
labels:
- traefik.enable=true
- traefik.http.routers.webmail.rule=Host(`webmail.sub.differentdomain.tld`) || Host(`webmail.sub.domain.tld`)
- traefik.http.routers.webmail.entrypoints=https
- traefik.http.routers.webmail.service=webmail
- traefik.http.services.webmail.loadbalancer.server.port=80
volumes:
acme:
certs:
networks:
proxy:
external: true
name: proxy stalwart config.toml authentication.fallback-admin.secret = "......................................................"
authentication.fallback-admin.user = "......"
certificate.default.cert = "%{file:/data/certs/mail.sub.domain.tld/cert.pem}%"
certificate.default.default = true
certificate.default.private-key = "%{file:/data/certs/mail.sub.domain.tld/key.pem}%"
directory.internal.store = "rocksdb"
directory.internal.type = "internal"
lookup.default.hostname = "mail.sub.domain.tld"
server.http.hsts = true
server.http.permissive-cors = false
server.http.url = "protocol + '://' + key_get('default', 'hostname') + ':' + local_port"
server.http.use-x-forwarded = true
server.listener.http.bind = "[::]:8080"
server.listener.http.protocol = "http"
server.listener.https.bind = "[::]:443"
server.listener.https.protocol = "http"
server.listener.https.tls.implicit = true
server.listener.imaptls.bind = "[::]:993"
server.listener.imaptls.protocol = "imap"
server.listener.imaptls.proxy.override = true
server.listener.imaptls.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.imaptls.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.imaptls.tls.implicit = true
server.listener.sieve.bind = "[::]:4190"
server.listener.sieve.protocol = "managesieve"
server.listener.sieve.proxy.override = true
server.listener.sieve.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.sieve.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.smtp.bind = "[::]:25"
server.listener.smtp.protocol = "smtp"
server.listener.smtp.proxy.override = true
server.listener.smtp.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.smtp.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.submission.bind = "[::]:587"
server.listener.submission.protocol = "smtp"
server.listener.submission.proxy.override = true
server.listener.submission.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.submission.proxy.trusted-networks.1 = "172.19.0.0/16"
storage.blob = "rocksdb"
storage.data = "rocksdb"
storage.directory = "internal"
storage.fts = "rocksdb"
storage.lookup = "rocksdb"
store.rocksdb.compression = "lz4"
store.rocksdb.path = "/opt/stalwart-mail/data"
store.rocksdb.type = "rocksdb"
tracer.log.ansi = false
tracer.log.enable = true
tracer.log.level = "trace"
tracer.log.lossy = false
tracer.log.path = "/opt/stalwart-mail/logs"
tracer.log.prefix = "stalwart.log"
tracer.log.rotate = "daily"
tracer.log.type = "log" traefik-dynamic.yml tls:
options:
default:
minVersion: VersionTLS12 So here I am I have all this, the certificates are valid, I can login to the webui of the server and I can also access the forntend of the webmail. But I first of all can't login to the webmail allthough I can login through thunderbird but not send anything. I can provide logs and everything, I just don't know which will be helpfull, so just ask me if you need some. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Hi, I suggest that you first try running Stalwart without any reverse proxies in the middle. Once you have it working then try configuring Traefik. If you are having issues set the log level to |
Beta Was this translation helpful? Give feedback.
-
So after some troubleshooting and a lot of headaches, I've managed to pull it off, I though I share it here, so that everyone who struggles after me can look at this. docker-compose.yml services:
traefik:
container_name: traefik
image: traefik:v3.0
restart: always
networks:
proxy:
ipv4_address: 172.19.0.2
ports:
- 80:80
- 443:443
- 25:25
- 587:587
- 465:465
- 993:993
- 4190:4190
volumes:
- /etc/localtime:/etc/localtime:ro
- ./traefik:/etc/traefik
- ./acme:/etc/certs
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- --certificatesresolvers.leresolver.acme.keyType=EC256
- --certificatesresolvers.leresolver.acme.tlschallenge=true
- --certificatesresolvers.leresolver.acme.email=totaly@valid.email
- --certificatesresolvers.leresolver.acme.storage=/etc/certs/acme.json
- --entrypoints.http.address=:80
- --entrypoints.http.http3
- --entrypoints.http.http.redirections.entrypoint.to=https
- --entrypoints.http.http.redirections.entrypoint.scheme=https
- --entrypoints.https.address=:443
- --entrypoints.https.http3
- --entrypoints.https.http.tls.certresolver=leresolver
- --entrypoints.smtp.address=:25
- --entrypoints.smtp.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --entrypoints.submission.address=:587
- --entrypoints.submission.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --entrypoints.submissions.address=:465
- --entrypoints.submissions.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --entrypoints.imaps.address=:993
- --entrypoints.imaps.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --entrypoints.managed-sieve.address=:4190
- --entrypoints.managed-sieve.proxyProtocol.trustedIPs=172.19.0.2,172.19.0.5
- --providers.docker=true
- --providers.docker.exposedByDefault=false
- --providers.file.filename=/etc/traefik/traefik-dynamic.yml
- --providers.file.watch=true
traefik-certs-dumper:
container_name: traefik-certs-dumper
image: ghcr.io/kereis/traefik-certs-dumper:latest
restart: unless-stopped
depends_on:
- traefik
volumes:
- /etc/localtime:/etc/localtime:ro
- ./acme:/traefik:ro
- certs:/output
mailserver:
container_name: stalwart
image: stalwartlabs/mail-server:latest
restart: unless-stopped
networks:
proxy:
ipv4_address: 172.19.0.5
volumes:
- /etc/localtime:/etc/localtime:ro
- ./stalwart-mail:/opt/stalwart-mail
- certs:/data/certs:ro
labels:
- traefik.enable=true
- traefik.http.routers.mailserver.rule=Host(`mail.subdomain.domain.tld`) || Host(`autodiscover.subdomain.domain.tld`) || Host(`autoconfig.subdomain.domain.tld`) || Host(`mta-sts.subdomain.domain.tld)
- traefik.http.routers.mailserver.entrypoints=https
- traefik.http.routers.mailserver.service=mailserver
- traefik.http.services.mailserver.loadbalancer.server.port=8080
- 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.jmap.rule=HostSNI(`*`)
- traefik.tcp.routers.jmap.tls.passthrough=true
- traefik.tcp.routers.jmap.entrypoints=https
- traefik.tcp.routers.jmap.service=jmap
- traefik.tcp.services.jmap.loadbalancer.server.port=443
- traefik.tcp.services.jmap.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.tls.passthrough=true
- 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.imaps.rule=HostSNI(`*`)
- traefik.tcp.routers.imaps.tls.passthrough=true
- 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.managed-sieve.rule=HostSNI(`*`)
- traefik.tcp.routers.managed-sieve.tls.passthrough=true
- traefik.tcp.routers.managed-sieve.entrypoints=managed-sieve
- traefik.tcp.routers.managed-sieve.service=managed-sieve
- traefik.tcp.services.managed-sieve.loadbalancer.server.port=4190
- traefik.tcp.services.managed-sieve.loadbalancer.proxyProtocol.version=2
roundcubemail:
container_name: roundcube
image: roundcube/roundcubemail:latest
restart: unless-stopped
networks:
proxy:
depends_on:
- mailserver
volumes:
- ./roundcube/www:/var/www/html
- ./roundcube/db/sqlite:/var/roundcube/db
- ./roundcube/config:/var/roundcube/config
environment:
ROUNDCUBEMAIL_DB_TYPE: sqlite
ROUNDCUBEMAIL_SKIN: elastic
ROUNDCUBEMAIL_DEFAULT_HOST: 'ssl://mail.subdomain.domain.tld'
ROUNDCUBEMAIL_DEFAULT_PORT: 993
ROUNDCUBEMAIL_SMTP_HOST: 'ssl://mail.subdomain.domain.tld'
ROUNDCUBEMAIL_SMTP_PORT: 465
ROUNDCUBEMAIL_PLUGINS: archive,zipdownload,database_attachments,managesieve
ROUNDCUBEMAIL_INSTALL_PLUGINS: 1
labels:
- traefik.enable=true
- traefik.http.routers.webmail.rule=Host(`webmail.subdomain.domain.tld`)
- traefik.http.routers.webmail.entrypoints=https
- traefik.http.routers.webmail.service=webmail
- traefik.http.services.webmail.loadbalancer.server.port=80
volumes:
certs:
networks:
proxy:
external: true
name: proxy stalwart-mail/etc/config.toml authentication.fallback-admin.secret = "....................................."
authentication.fallback-admin.user = "........................................."
certificate.default.cert = "%{file:/data/certs/mail.subdomain.domain.tld/cert.pem}%"
certificate.default.default = true
certificate.default.private-key = "%{file:/data/certs/mail.subdomain.domain.tld/key.pem}%"
directory.internal.store = "rocksdb"
directory.internal.type = "internal"
lookup.default.hostname = "mail.subdomain.domain.tld"
server.http.hsts = true
server.http.permissive-cors = false
server.http.url = "protocol + '://' + key_get('default', 'hostname') + ':' + local_port"
server.http.use-x-forwarded = true
server.listener.http.bind = "[::]:8080"
server.listener.http.protocol = "http"
server.listener.https.bind = "[::]:443"
server.listener.https.protocol = "http"
server.listener.https.tls.implicit = true
server.listener.imaptls.bind = "[::]:993"
server.listener.imaptls.protocol = "imap"
server.listener.imaptls.proxy.override = true
server.listener.imaptls.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.imaptls.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.imaptls.tls.implicit = true
server.listener.sieve.bind = "[::]:4190"
server.listener.sieve.protocol = "managesieve"
server.listener.sieve.proxy.override = true
server.listener.sieve.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.sieve.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.sieve.socket.override = false
server.listener.sieve.tls.implicit = true
server.listener.sieve.tls.override = false
server.listener.smtp.bind = "[::]:25"
server.listener.smtp.protocol = "smtp"
server.listener.smtp.proxy.override = true
server.listener.smtp.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.smtp.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.submission.bind = "[::]:587"
server.listener.submission.protocol = "smtp"
server.listener.submission.proxy.override = true
server.listener.submission.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.submission.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.submissions.bind = "[::]:465"
server.listener.submissions.protocol = "smtp"
server.listener.submissions.proxy.override = true
server.listener.submissions.proxy.trusted-networks.0 = "172.119.0.2"
server.listener.submissions.proxy.trusted-networks.1 = "172.19.0.0/16"
server.listener.submissions.socket.override = false
server.listener.submissions.tls.implicit = true
server.listener.submissions.tls.override = false
storage.blob = "rocksdb"
storage.data = "rocksdb"
storage.directory = "internal"
storage.fts = "rocksdb"
storage.lookup = "rocksdb"
store.rocksdb.compression = "lz4"
store.rocksdb.path = "/opt/stalwart-mail/data"
store.rocksdb.type = "rocksdb"
tracer.log.ansi = false
tracer.log.enable = true
tracer.log.level = "info"
tracer.log.lossy = false
tracer.log.path = "/opt/stalwart-mail/logs"
tracer.log.prefix = "stalwart.log"
tracer.log.rotate = "daily"
tracer.log.type = "log" roundcube/config/config.sieve.inc.php <?php
$config['managesieve_port'] = 4190;
$config['managesieve_host'] = 'ssl://mail.subdomain.domain.tld';
?> That's all there is and was, well also some prot forwarding and Firewall configuration, but that's completely individual. |
Beta Was this translation helpful? Give feedback.
So after some troubleshooting and a lot of headaches, I've managed to pull it off, I though I share it here, so that everyone who struggles after me can look at this.
docker-compose.yml