Skip to content

Commit 266bfb1

Browse files
committedSep 30, 2021
New: Add a bunch of examples
Hopefully this exampels will help people get up to speed and deploy the solution faster. They show how the image can be used in different scenarios, e.g.: - as a MTA for Dovecot with `docker-compose` - as an outgoing queue towards AWS SES or Google Mail through `helm` - as an outgoing queue towards Sendgrid through `helm`
1 parent 90eafda commit 266bfb1

File tree

7 files changed

+319
-0
lines changed

7 files changed

+319
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
2+
# vim: noai:ts=2:sw=2:expandtab
3+
#
4+
# This example shows how this image can be used as a MTA in combination with Dovecot. Dovecot
5+
# is used for authentication here. The example is not complete, but should give you a general
6+
# overview of how flexible the image is.
7+
#
8+
version: "3.8"
9+
services:
10+
solr: # solr is used by Dovecot for full-text search and indexing
11+
image: solr:7.7
12+
container_name: solr
13+
deploy:
14+
resources:
15+
limits:
16+
cpus: '0.5'
17+
memory: '512M'
18+
reservations:
19+
cpus: '0.02'
20+
memory: '32M'
21+
ports:
22+
- 8983:8983
23+
restart: unless-stopped
24+
volumes:
25+
- ./solr/data:/opt/solr/server/solr
26+
- ./solr/logs:/opt/solr/server/logs
27+
28+
tika: # Tika is used by Dovecot for extracing text from DOC, DOCX, PDF and other files
29+
image: apache/tika
30+
container_name: tika
31+
build:
32+
context: ./tika/docker
33+
deploy:
34+
resources:
35+
limits:
36+
cpus: '0.2'
37+
memory: '512M'
38+
reservations:
39+
cpus: '0.02'
40+
memory: '64M'
41+
restart: unless-stopped
42+
ports:
43+
- 9998:9998
44+
45+
dovecot: # Main Dovecot container
46+
image: dovecot/dovecot
47+
container_name: dovecot
48+
build:
49+
context: ./dovecot/docker
50+
deploy:
51+
resources:
52+
limits:
53+
cpus: '0.5'
54+
memory: '128M'
55+
reservations:
56+
cpus: '0.02'
57+
memory: '32M'
58+
restart: unless-stopped
59+
network_mode: host
60+
entrypoint: /usr/sbin/dovecot
61+
command:
62+
- -F
63+
- -c
64+
- /etc/dovecot/dovecot.conf
65+
volumes:
66+
- ./mail:/store/mail # All mail will be stored here
67+
- ./dovecot/run:/var/run/dovecot
68+
- ./dovecot/conf:/etc/dovecot # Dovecot configuration files
69+
- ./dovecot/auth:/var/spool/postfix/private/dovecot # Dovecot authentication socket
70+
- ./certs:/etc/letsencrypt # Certificates used by dovecot
71+
72+
postfix: # The MTA
73+
image: boky/postfix
74+
container_name: postfix
75+
deploy:
76+
resources:
77+
limits:
78+
cpus: '0.2'
79+
memory: '128M'
80+
reservations:
81+
cpus: '0.02'
82+
memory: '32M'
83+
restart: unless-stopped
84+
network_mode: host
85+
environment:
86+
ALLOW_EMPTY_SENDER_DOMAINS: "1" # Allow any recipient
87+
FORCE_COLOR: "1" # Force color
88+
POSTFIX_smtp_sender_dependent_authentication: "yes" # Clients should authenticate
89+
POSTFIX_sender_dependent_relayhost_maps: "lmdb:/etc/postfix/sender_dependent_relayhost" # Different relay MTAs for different domains
90+
POSTFIX_smtp_sasl_auth_enable: "yes" # Enable SASL
91+
POSTFIX_smtp_sasl_password_maps: "lmdb:/etc/postfix/sasl_password" # List of passwords (for outgoing MTAs)
92+
POSTFIX_smtp_sasl_security_options: "noanonymous" # Always authenticate towards relay hosts
93+
POSTFIX_smtp_sasl_mechanism_filter: "login, plain, digest-md5" # Login with these credentials
94+
POSTFIX_smtpd_tls_cert_file: "/etc/letsencrypt/live/mail.example.com/fullchain.pem" # Public part of key, updated by Letsencrypt
95+
POSTFIX_smtpd_tls_key_file: "/etc/letsencrypt/live/mail.example.com/privkey.pem" # Private part of key, updated by Letsencrypt
96+
POSTFIX_smtpd_use_tls: "yes" # Enable TLS
97+
POSTFIX_smtpd_tls_session_cache_database: "lmdb:${data_directory}/smtpd_scache"
98+
POSTFIX_smtp_tls_session_cache_database: "lmdb:${data_directory}/smtp_scache"
99+
POSTFIX_smtp_tls_loglevel: "1"
100+
POSTFIX_smtpd_tls_security_level: "may"
101+
POSTFIX_smtpd_tls_protocols: "TLSv1.2, TLSv1.1, TLSv1, !SSLv2"
102+
POSTFIX_smtpd_relay_restrictions: "permit_sasl_authenticated, reject_unauth_destination"
103+
POSTFIX_smtpd_sasl_auth_enable: "yes"
104+
POSTFIX_smtpd_sasl_type: "dovecot" # Authenticate using Dovecot
105+
POSTFIX_smtpd_sasl_path: "private/dovecot/auth" # Path to Dovecot socket
106+
POSTFIX_smtpd_sasl_authenticated_header: "yes"
107+
POSTFIX_smtpd_sasl_security_options: "noanonymous" # Don't allow non-authenticated connections
108+
POSTFIX_smtpd_sasl_local_domain: "$myhostname"
109+
POSTFIX_broken_sasl_auth_clients: "yes"
110+
POSTFIX_smtpd_recipient_restrictions: "reject_non_fqdn_recipient, reject_non_fqdn_sender, reject_unlisted_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination"
111+
POSTFIX_smtpd_sender_restrictions: "reject_unknown_sender_domain"
112+
POSTFIX_smtpd_client_restrictions: ""
113+
POSTFIX_virtual_transport: "lmtp:unix:/var/run/dovecot/lmtp" # Deliver (send) mail to Dovecot
114+
POSTFIX_smtp_use_tls: "yes"
115+
POSTFIX_smtpd_tls_received_header: "yes"
116+
POSTFIX_smtpd_tls_mandatory_protocols: "!SSLv2, !SSLv3, !TLSv1.0, !TLSv1.1"
117+
POSTFIX_smtpd_tls_mandatory_ciphers: "high"
118+
POSTFIX_smtpd_tls_mandatory_exclude_ciphers: "aNULL, MD5, DSS, SSLv2 EXPORT LOW 3DES"
119+
POSTFIX_smtpd_tls_exclude_ciphers: "aNULL, MD5, DSS, SSLv2 EXPORT LOW 3DES"
120+
POSTFIX_smtpd_tls_auth_only: "yes"
121+
POSTFIX_tls_random_source: "dev:/dev/urandom"
122+
POSTFIX_message_size_limit: "40960000"
123+
volumes:
124+
- /dev/urandom:/dev/urandom
125+
- ./postfix/sasl_password:/etc/postfix/sasl_password # List of passwords for upstream MTAs
126+
- ./postfix/sender_dependent_relayhost:/etc/postfix/sender_dependent_relayhost # List of domains for upstream MTAs
127+
- ./postfix/smtp_tls_policy:/etc/postfix/smtp_tls_policy # Different upstreams MTAs have different encryption connection policy
128+
- ./postfix/init:/docker-init.db # Run 3rd-party init scripts at startup
129+
- ./dovecot/run:/var/run/dovecot # Map Dovecot run directory
130+
- ./dovecot/auth:/var/spool/postfix/private/dovecot # Map Dovecot auth socket
131+
- ./certs:/etc/letsencrypt # Inject certificates
132+
133+
rainloop: # Build webmail client
134+
image: bokysan/rainloop
135+
container_name: rainloop
136+
build:
137+
context: ./rainloop/rainloop
138+
deploy:
139+
resources:
140+
limits:
141+
cpus: '0.2'
142+
memory: '512M'
143+
reservations:
144+
cpus: '0.02'
145+
memory: '32M'
146+
restart: unless-stopped
147+
environment:
148+
- UPLOAD_MAX_SIZE=200M
149+
volumes:
150+
- ./rainloop/data:/rainloop/data
151+
- ./certs:/etc/letsencrypt
152+
labels:
153+
- "traefik.enable=true"
154+
- "traefik.http.services.rainloop.loadbalancer.server.port=8888"
155+
- "traefik.http.routers.rainloop.rule=Host(`mail.example.com`) && PathPrefix(`/`)"
156+
- "traefik.http.routers.rainloop.entrypoints=websecure"
157+
- "traefik.http.routers.rainloop.tls.certresolver=le"
158+
159+
zpush: # Build activesync client, to pass through those pesky firewalls
160+
image: bokysan/activesync
161+
container_name: activesync
162+
build:
163+
context: ./zpush/docker
164+
deploy:
165+
resources:
166+
limits:
167+
cpus: '0.2'
168+
memory: '512M'
169+
reservations:
170+
cpus: '0.02'
171+
memory: '32M'
172+
restart: unless-stopped
173+
volumes:
174+
- ./zpush/log:/var/log/z-push
175+
- ./zpush/data:/var/lib/z-push
176+
labels:
177+
- "traefik.enable=true"
178+
- "traefik.http.services.activesync.loadbalancer.server.port=80"
179+
- "traefik.http.routers.activesync.rule=Host(`mail.example.com`) && PathPrefix(`/Microsoft-Server-ActiveSync`)"
180+
- "traefik.http.routers.activesync.entrypoints=websecure"
181+
- "traefik.http.routers.activesync.tls.certresolver=le"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/sh
2+
chown root:root /etc/postfix/sender_dependent_relayhost
3+
postmap /etc/postfix/sender_dependent_relayhost
4+
5+
chown root:root /etc/postfix/sasl_password
6+
postmap /etc/postfix/sasl_password
7+
8+
chown root:root /etc/postfix/smtp_tls_policy
9+
postmap /etc/postfix/smtp_tls_policy
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
demo@example.org demo:aabbccddeeff
2+
demo@example.net demo:ffeeddccbbaa
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
demo@example.org [mail.example.org]:10025
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[mail.example.org]:10025 encrypt
2+
[smtp.gmail.com]:587 secure
3+
[127.0.0.1]:20025 none
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
replicaCount: 1
2+
resources:
3+
limits:
4+
cpu: 200m
5+
memory: 128Mi
6+
requests:
7+
cpu: 100m
8+
memory: 128Mi
9+
10+
# priorityClassName: mail
11+
extraVolumes:
12+
- name: config
13+
configMap:
14+
name: postfix-mail
15+
extraVolumeMounts:
16+
- mountPath: /docker-init.db/startup.sh
17+
subPath: startup.sh
18+
name: config
19+
20+
persistence:
21+
enabled: true
22+
storageClass: "gp3"
23+
24+
secret:
25+
AWS_SMTP_SERVER: email-smtp.eu-central-1.amazonaws.com
26+
AWS_IAM_USER: smtp-user
27+
AWS_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXX
28+
AWS_SECRET_KEY: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
29+
AWS_SMTP_PASSWORD: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
30+
31+
config:
32+
general:
33+
TZ: "Europe/London"
34+
35+
# Default relay with go to Google, but for example.com and example.org it will go to AWS
36+
# No password provided for Google as it will be authenticated via IP
37+
RELAYHOST: "smtp-relay.gmail.com:587"
38+
ALLOWED_SENDER_DOMAINS: "example.com example.org example.net"
39+
LOG_FORMAT: "json"
40+
41+
startup.sh: |
42+
#!/bin/sh
43+
set -e
44+
45+
RELAY_MAPS=/etc/postfix/relay_maps
46+
SASL_PASSWD=/etc/postfix/sasl_passwd
47+
48+
: > $RELAY_MAPS
49+
cat > $RELAY_MAPS <<EOF
50+
@example.com [${AWS_SMTP_SERVER}]:587
51+
@example.org [${AWS_SMTP_SERVER}]:587
52+
EOF
53+
postmap /etc/postfix/relay_maps
54+
55+
: > $SASL_PASSWD
56+
cat > $SASL_PASSWD <<EOF
57+
[${AWS_SMTP_SERVER}]:587 ${AWS_ACCESS_KEY}:${AWS_SMTP_PASSWORD}
58+
EOF
59+
60+
postmap /etc/postfix/sasl_passwd
61+
62+
postfix:
63+
sender_dependent_relayhost_maps: "lmdb:/etc/postfix/relay_maps"
64+
smtp_sasl_auth_enable: "yes"
65+
smtp_sasl_password_maps: "lmdb:/etc/postfix/sasl_passwd"
66+
smtp_sasl_security_options: "noanonymous"
67+
smtp_tls_security_level: "encrypt"
68+
smtp_tls_note_starttls_offer: "yes"
69+
70+
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
replicaCount: 1
2+
resources:
3+
limits:
4+
cpu: 200m
5+
memory: 128Mi
6+
requests:
7+
cpu: 100m
8+
memory: 128Mi
9+
10+
# priorityClassName: mail
11+
extraVolumes:
12+
- name: config
13+
configMap:
14+
name: postfix-mail
15+
extraVolumeMounts:
16+
- mountPath: /docker-init.db/startup.sh
17+
subPath: startup.sh
18+
name: config
19+
20+
persistence:
21+
enabled: true
22+
storageClass: "standard"
23+
24+
secret:
25+
SENDGRID_SMTP_SERVER: smtp.sendgrid.net
26+
SENDGRID_API_KEY: "XXXXYYYYZZZZ"
27+
28+
config:
29+
general:
30+
TZ: "Europe/London"
31+
RELAYHOST: "smtp.sendgrid.net:587"
32+
ALLOWED_SENDER_DOMAINS: "example.com example.org example.net"
33+
LOG_FORMAT: "json"
34+
35+
startup.sh: |
36+
#!/bin/sh
37+
set -e
38+
39+
SASL_PASSWD=/etc/postfix/sasl_passwd
40+
41+
: > $SASL_PASSWD
42+
cat > $SASL_PASSWD <<EOF
43+
[${SENDGRID_SMTP_SERVER}]:587 apikey:${SENDGRID_API_KEY}
44+
EOF
45+
46+
postmap /etc/postfix/sasl_passwd
47+
48+
postfix:
49+
smtp_sasl_auth_enable: "yes"
50+
smtp_sasl_password_maps: "lmdb:/etc/postfix/sasl_passwd"
51+
smtp_sasl_security_options: "noanonymous"
52+
smtp_tls_security_level: "encrypt"
53+
smtp_tls_note_starttls_offer: "yes"

0 commit comments

Comments
 (0)
Please sign in to comment.