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`
This commit is contained in:
Bojan Čekrlić 2021-09-29 12:19:16 +02:00
parent 90eafda79e
commit 266bfb1ba0
7 changed files with 319 additions and 0 deletions

View file

@ -0,0 +1,181 @@
# vim: noai:ts=2:sw=2:expandtab
#
# This example shows how this image can be used as a MTA in combination with Dovecot. Dovecot
# is used for authentication here. The example is not complete, but should give you a general
# overview of how flexible the image is.
#
version: "3.8"
services:
solr: # solr is used by Dovecot for full-text search and indexing
image: solr:7.7
container_name: solr
deploy:
resources:
limits:
cpus: '0.5'
memory: '512M'
reservations:
cpus: '0.02'
memory: '32M'
ports:
- 8983:8983
restart: unless-stopped
volumes:
- ./solr/data:/opt/solr/server/solr
- ./solr/logs:/opt/solr/server/logs
tika: # Tika is used by Dovecot for extracing text from DOC, DOCX, PDF and other files
image: apache/tika
container_name: tika
build:
context: ./tika/docker
deploy:
resources:
limits:
cpus: '0.2'
memory: '512M'
reservations:
cpus: '0.02'
memory: '64M'
restart: unless-stopped
ports:
- 9998:9998
dovecot: # Main Dovecot container
image: dovecot/dovecot
container_name: dovecot
build:
context: ./dovecot/docker
deploy:
resources:
limits:
cpus: '0.5'
memory: '128M'
reservations:
cpus: '0.02'
memory: '32M'
restart: unless-stopped
network_mode: host
entrypoint: /usr/sbin/dovecot
command:
- -F
- -c
- /etc/dovecot/dovecot.conf
volumes:
- ./mail:/store/mail # All mail will be stored here
- ./dovecot/run:/var/run/dovecot
- ./dovecot/conf:/etc/dovecot # Dovecot configuration files
- ./dovecot/auth:/var/spool/postfix/private/dovecot # Dovecot authentication socket
- ./certs:/etc/letsencrypt # Certificates used by dovecot
postfix: # The MTA
image: boky/postfix
container_name: postfix
deploy:
resources:
limits:
cpus: '0.2'
memory: '128M'
reservations:
cpus: '0.02'
memory: '32M'
restart: unless-stopped
network_mode: host
environment:
ALLOW_EMPTY_SENDER_DOMAINS: "1" # Allow any recipient
FORCE_COLOR: "1" # Force color
POSTFIX_smtp_sender_dependent_authentication: "yes" # Clients should authenticate
POSTFIX_sender_dependent_relayhost_maps: "lmdb:/etc/postfix/sender_dependent_relayhost" # Different relay MTAs for different domains
POSTFIX_smtp_sasl_auth_enable: "yes" # Enable SASL
POSTFIX_smtp_sasl_password_maps: "lmdb:/etc/postfix/sasl_password" # List of passwords (for outgoing MTAs)
POSTFIX_smtp_sasl_security_options: "noanonymous" # Always authenticate towards relay hosts
POSTFIX_smtp_sasl_mechanism_filter: "login, plain, digest-md5" # Login with these credentials
POSTFIX_smtpd_tls_cert_file: "/etc/letsencrypt/live/mail.example.com/fullchain.pem" # Public part of key, updated by Letsencrypt
POSTFIX_smtpd_tls_key_file: "/etc/letsencrypt/live/mail.example.com/privkey.pem" # Private part of key, updated by Letsencrypt
POSTFIX_smtpd_use_tls: "yes" # Enable TLS
POSTFIX_smtpd_tls_session_cache_database: "lmdb:${data_directory}/smtpd_scache"
POSTFIX_smtp_tls_session_cache_database: "lmdb:${data_directory}/smtp_scache"
POSTFIX_smtp_tls_loglevel: "1"
POSTFIX_smtpd_tls_security_level: "may"
POSTFIX_smtpd_tls_protocols: "TLSv1.2, TLSv1.1, TLSv1, !SSLv2"
POSTFIX_smtpd_relay_restrictions: "permit_sasl_authenticated, reject_unauth_destination"
POSTFIX_smtpd_sasl_auth_enable: "yes"
POSTFIX_smtpd_sasl_type: "dovecot" # Authenticate using Dovecot
POSTFIX_smtpd_sasl_path: "private/dovecot/auth" # Path to Dovecot socket
POSTFIX_smtpd_sasl_authenticated_header: "yes"
POSTFIX_smtpd_sasl_security_options: "noanonymous" # Don't allow non-authenticated connections
POSTFIX_smtpd_sasl_local_domain: "$myhostname"
POSTFIX_broken_sasl_auth_clients: "yes"
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"
POSTFIX_smtpd_sender_restrictions: "reject_unknown_sender_domain"
POSTFIX_smtpd_client_restrictions: ""
POSTFIX_virtual_transport: "lmtp:unix:/var/run/dovecot/lmtp" # Deliver (send) mail to Dovecot
POSTFIX_smtp_use_tls: "yes"
POSTFIX_smtpd_tls_received_header: "yes"
POSTFIX_smtpd_tls_mandatory_protocols: "!SSLv2, !SSLv3, !TLSv1.0, !TLSv1.1"
POSTFIX_smtpd_tls_mandatory_ciphers: "high"
POSTFIX_smtpd_tls_mandatory_exclude_ciphers: "aNULL, MD5, DSS, SSLv2 EXPORT LOW 3DES"
POSTFIX_smtpd_tls_exclude_ciphers: "aNULL, MD5, DSS, SSLv2 EXPORT LOW 3DES"
POSTFIX_smtpd_tls_auth_only: "yes"
POSTFIX_tls_random_source: "dev:/dev/urandom"
POSTFIX_message_size_limit: "40960000"
volumes:
- /dev/urandom:/dev/urandom
- ./postfix/sasl_password:/etc/postfix/sasl_password # List of passwords for upstream MTAs
- ./postfix/sender_dependent_relayhost:/etc/postfix/sender_dependent_relayhost # List of domains for upstream MTAs
- ./postfix/smtp_tls_policy:/etc/postfix/smtp_tls_policy # Different upstreams MTAs have different encryption connection policy
- ./postfix/init:/docker-init.db # Run 3rd-party init scripts at startup
- ./dovecot/run:/var/run/dovecot # Map Dovecot run directory
- ./dovecot/auth:/var/spool/postfix/private/dovecot # Map Dovecot auth socket
- ./certs:/etc/letsencrypt # Inject certificates
rainloop: # Build webmail client
image: bokysan/rainloop
container_name: rainloop
build:
context: ./rainloop/rainloop
deploy:
resources:
limits:
cpus: '0.2'
memory: '512M'
reservations:
cpus: '0.02'
memory: '32M'
restart: unless-stopped
environment:
- UPLOAD_MAX_SIZE=200M
volumes:
- ./rainloop/data:/rainloop/data
- ./certs:/etc/letsencrypt
labels:
- "traefik.enable=true"
- "traefik.http.services.rainloop.loadbalancer.server.port=8888"
- "traefik.http.routers.rainloop.rule=Host(`mail.example.com`) && PathPrefix(`/`)"
- "traefik.http.routers.rainloop.entrypoints=websecure"
- "traefik.http.routers.rainloop.tls.certresolver=le"
zpush: # Build activesync client, to pass through those pesky firewalls
image: bokysan/activesync
container_name: activesync
build:
context: ./zpush/docker
deploy:
resources:
limits:
cpus: '0.2'
memory: '512M'
reservations:
cpus: '0.02'
memory: '32M'
restart: unless-stopped
volumes:
- ./zpush/log:/var/log/z-push
- ./zpush/data:/var/lib/z-push
labels:
- "traefik.enable=true"
- "traefik.http.services.activesync.loadbalancer.server.port=80"
- "traefik.http.routers.activesync.rule=Host(`mail.example.com`) && PathPrefix(`/Microsoft-Server-ActiveSync`)"
- "traefik.http.routers.activesync.entrypoints=websecure"
- "traefik.http.routers.activesync.tls.certresolver=le"

View file

@ -0,0 +1,9 @@
#!/bin/sh
chown root:root /etc/postfix/sender_dependent_relayhost
postmap /etc/postfix/sender_dependent_relayhost
chown root:root /etc/postfix/sasl_password
postmap /etc/postfix/sasl_password
chown root:root /etc/postfix/smtp_tls_policy
postmap /etc/postfix/smtp_tls_policy

View file

@ -0,0 +1,2 @@
demo@example.org demo:aabbccddeeff
demo@example.net demo:ffeeddccbbaa

View file

@ -0,0 +1 @@
demo@example.org [mail.example.org]:10025

View file

@ -0,0 +1,3 @@
[mail.example.org]:10025 encrypt
[smtp.gmail.com]:587 secure
[127.0.0.1]:20025 none

View file

@ -0,0 +1,70 @@
replicaCount: 1
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
# priorityClassName: mail
extraVolumes:
- name: config
configMap:
name: postfix-mail
extraVolumeMounts:
- mountPath: /docker-init.db/startup.sh
subPath: startup.sh
name: config
persistence:
enabled: true
storageClass: "gp3"
secret:
AWS_SMTP_SERVER: email-smtp.eu-central-1.amazonaws.com
AWS_IAM_USER: smtp-user
AWS_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXX
AWS_SECRET_KEY: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
AWS_SMTP_PASSWORD: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
config:
general:
TZ: "Europe/London"
# Default relay with go to Google, but for example.com and example.org it will go to AWS
# No password provided for Google as it will be authenticated via IP
RELAYHOST: "smtp-relay.gmail.com:587"
ALLOWED_SENDER_DOMAINS: "example.com example.org example.net"
LOG_FORMAT: "json"
startup.sh: |
#!/bin/sh
set -e
RELAY_MAPS=/etc/postfix/relay_maps
SASL_PASSWD=/etc/postfix/sasl_passwd
: > $RELAY_MAPS
cat > $RELAY_MAPS <<EOF
@example.com [${AWS_SMTP_SERVER}]:587
@example.org [${AWS_SMTP_SERVER}]:587
EOF
postmap /etc/postfix/relay_maps
: > $SASL_PASSWD
cat > $SASL_PASSWD <<EOF
[${AWS_SMTP_SERVER}]:587 ${AWS_ACCESS_KEY}:${AWS_SMTP_PASSWORD}
EOF
postmap /etc/postfix/sasl_passwd
postfix:
sender_dependent_relayhost_maps: "lmdb:/etc/postfix/relay_maps"
smtp_sasl_auth_enable: "yes"
smtp_sasl_password_maps: "lmdb:/etc/postfix/sasl_passwd"
smtp_sasl_security_options: "noanonymous"
smtp_tls_security_level: "encrypt"
smtp_tls_note_starttls_offer: "yes"

View file

@ -0,0 +1,53 @@
replicaCount: 1
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
# priorityClassName: mail
extraVolumes:
- name: config
configMap:
name: postfix-mail
extraVolumeMounts:
- mountPath: /docker-init.db/startup.sh
subPath: startup.sh
name: config
persistence:
enabled: true
storageClass: "standard"
secret:
SENDGRID_SMTP_SERVER: smtp.sendgrid.net
SENDGRID_API_KEY: "XXXXYYYYZZZZ"
config:
general:
TZ: "Europe/London"
RELAYHOST: "smtp.sendgrid.net:587"
ALLOWED_SENDER_DOMAINS: "example.com example.org example.net"
LOG_FORMAT: "json"
startup.sh: |
#!/bin/sh
set -e
SASL_PASSWD=/etc/postfix/sasl_passwd
: > $SASL_PASSWD
cat > $SASL_PASSWD <<EOF
[${SENDGRID_SMTP_SERVER}]:587 apikey:${SENDGRID_API_KEY}
EOF
postmap /etc/postfix/sasl_passwd
postfix:
smtp_sasl_auth_enable: "yes"
smtp_sasl_password_maps: "lmdb:/etc/postfix/sasl_passwd"
smtp_sasl_security_options: "noanonymous"
smtp_tls_security_level: "encrypt"
smtp_tls_note_starttls_offer: "yes"