blob: 654f26442fa9fd3c24897261e3334ef1fbf2d3bc (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
services:
roundcube:
image: roundcube/roundcubemail:latest-nonroot
restart: always
volumes:
- {{ mail_base }}/volumes/data/roundcube/db:/var/roundcube/db
- {{ mail_base }}/volumes/data/roundcube/config:/var/roundcube/config
environment:
- ROUNDCUBEMAIL_DB_TYPE=sqlite
- ROUNDCUBEMAIL_SKIN=elastic
- ROUNDCUBEMAIL_PLUGINS={{ roundcube_plugins }}
- ROUNDCUBEMAIL_DEFAULT_HOST={{ roundcube_default_host }}
- ROUNDCUBEMAIL_DEFAULT_PORT={{ roundcube_default_port }}
- ROUNDCUBEMAIL_SMTP_SERVER={{ roundcube_smtp_host }}
- ROUNDCUBEMAIL_SMTP_PORT={{ roundcube_smtp_port }}
networks:
- proxy
- roundcube
deploy:
mode: replicated
replicas: 1
labels:
- traefik.enable=true
- traefik.swarm.network=proxy
- traefik.http.routers.mail.tls=true
- traefik.http.routers.mail.tls.certResolver=letsencrypt
- traefik.http.routers.mail.rule=Host(`{{ mail_domain }}`)
- traefik.http.routers.mail.entrypoints=websecure
- traefik.http.services.mail.loadbalancer.server.port=8000
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
hostname: {{ mail_domain }}
{% if homelab_build %}
command:
- /bin/sh
- -c
- |
[ ! -f "/etc/letsencrypt/live/{{ mail_domain }}" ] && sleep 60 # Sleep until certificate requested from traefik
supervisord -c /etc/supervisor/supervisord.conf
healthcheck:
disable: true
{% endif %}
deploy:
mode: replicated
replicas: 1
labels:
- traefik.enable=true
- traefik.swarm.network=proxy
# ManageSieve
- traefik.tcp.routers.sieve.tls.passthrough=true
- 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
# IMAP
- traefik.tcp.routers.imap.tls.passthrough=true
- 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=993
# SMTP
- traefik.tcp.routers.smtp.tls.passthrough=true
- 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=465
volumes:
- {{ mail_base }}/volumes/data/dms/vmail:/var/mail/
- {{ mail_base }}/volumes/data/dms/mail-state:/var/mail-state/
- {{ mail_base }}/volumes/data/dms/mail-logs:/var/log/mail/
- {{ mail_base }}/volumes/data/dms/config:/tmp/docker-mailserver/
- {{ mail_base }}/volumes/data/dms/config/dovecot-ldap.conf:/etc/dovecot/dovecot-ldap.conf.ext
- {{ letsencrypt_certs }}:/certs/:ro
- /etc/localtime:/etc/localtime:ro
environment:
- SSL_TYPE=manual
- SSL_CERT_PATH=/certs/{{ mail_domain }}.pem
- SSL_KEY_PATH=/certs/{{ mail_domain }}.key
- ENABLE_CLAMAV=0
- ENABLE_AMAVIS=0
- ENABLE_FAIL2BAN=1
- ENABLE_SASLAUTHD=1
- ENABLE_MANAGESIEVE=1
- ENABLE_POSTGREY=0
- SPOOF_PROTECTION=1
- ACCOUNT_PROVISIONER=LDAP
- LDAP_SERVER_HOST={{ ldap_server_host }}
- LDAP_SEARCH_BASE={{ ldap_search_base }}
- LDAP_BIND_DN={{ ldap_bind_dn }}
- LDAP_BIND_PW={{ email_ldap_api_token }}
- LDAP_QUERY_FILTER_USER={{ ldap_query_filter_user }}
- LDAP_QUERY_FILTER_GROUP={{ ldap_query_filter_group }}
- LDAP_QUERY_FILTER_ALIAS={{ ldap_query_filter_alias }}
- LDAP_QUERY_FILTER_DOMAIN={{ ldap_query_filter_domain }}
- LDAP_QUERY_FILTER_SENDERS={{ ldap_query_filter_senders }}
- POSTMASTER_ADDRESS={{ postmaster_email }}
- SASLAUTHD_MECHANISMS=ldap
- SASLAUTHD_LDAP_FILTER={{ sasl_ldap_filter }}
- ENABLE_OAUTH2=1
- OAUTH2_INTROSPECTION_URL={{ roundcube_oauth2_user_uri }}
- DEFAULT_RELAY_HOST={{ default_relay_host }}
- RELAY_USER={{ relay_user }}
- RELAY_PASSWORD={{ relay_password }}
networks:
- mailserver
- proxy
networks:
mailserver:
roundcube:
proxy:
external: true
|