Skip to content

Commit

Permalink
New: Add a bunch of examples
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bokysan committed Sep 30, 2021
1 parent 90eafda commit 266bfb1
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 0 deletions.
181 changes: 181 additions & 0 deletions examples/docker/mail-station/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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"
9 changes: 9 additions & 0 deletions examples/docker/mail-station/postfix/init/postmap.sh
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions examples/docker/mail-station/postfix/sasl_password
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
demo@example.org demo:aabbccddeeff
demo@example.net demo:ffeeddccbbaa
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
demo@example.org [mail.example.org]:10025
3 changes: 3 additions & 0 deletions examples/docker/mail-station/postfix/smtp_tls_policy
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[mail.example.org]:10025 encrypt
[smtp.gmail.com]:587 secure
[127.0.0.1]:20025 none
70 changes: 70 additions & 0 deletions examples/kubernetes/aws-ses-with-google-values.yml
Original file line number Diff line number Diff line change
@@ -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"


53 changes: 53 additions & 0 deletions examples/kubernetes/sendgrid-values.yml
Original file line number Diff line number Diff line change
@@ -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"

0 comments on commit 266bfb1

Please sign in to comment.