From 2d1bbb41f74bfeef066a09b277a80ded192f32a1 Mon Sep 17 00:00:00 2001 From: 3wc <3wc.git@doesthisthing.work> Date: Sat, 26 Sep 2020 16:18:02 +0200 Subject: [PATCH] Update README and options --- .envrc.sample | 10 +++++++++- README.md | 30 +++++++++++++++++++++++++++++- compose.yml | 38 ++++++++++++++++++++++++++------------ 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/.envrc.sample b/.envrc.sample index fcacec4..a94c4d6 100644 --- a/.envrc.sample +++ b/.envrc.sample @@ -1,4 +1,12 @@ export SERVICE=postfix_relay -export DOMAIN=postfix-relay.example.com +export DOMAIN=example.com export STACK_NAME=postfix_relay export LETS_ENCRYPT_ENV=production + +# Postfix options, see +# https://github.com/bokysan/docker-postfix#configuration-options +#export TZ=Europe/London +#export INBOUND_DEBUGGING=1 + +# $DOMAIN will be added by default, specify any more here: +#export EXTRA_SENDER_DOMAINS="app.example.com" diff --git a/README.md b/README.md index 74f8535..392c55e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,22 @@ # Postfix-Relay -Simple SMTP server / postfix null relay host • https://github.com/bokysan/docker-postfix +Centralised email delivery for all your `compose-stacks` apps using the +[`boky/postfix`] outgoing-only mail image. + +The basic idea is to run one instance of this on each swarm, and configure that +swarm's apps to send all their email through it. + +By default, this stack will try to deliver e-mail directly (i.e. looking up the +recipient's mail server using `MX` records). For this to work, you will need to +set up reverse DNS and SPF. + +Alternatively, you can easily route mail through a smarthost / relay host like +Mailgun or Gandi -- see [`RELAYHOST` and related parameters][boky-postfix-options]. + +FIXME 3wc: Pass `RELAYHOST` etc. from `.envrc` to service + +TODO 3wc: Can you run more than one instance of this on a swarm? How could we handle +that in terms of reverse DNS? ## Basic usage @@ -13,5 +29,17 @@ Simple SMTP server / postfix null relay host • https://github.com/bokysan/dock 5. `direnv allow` (or `. .envrc`) 6. `abra deploy` +## Using this in other stacks + +Add the other service to the (internal) `mail` network, and set whatever options +the image supports for auto-configuring SMTP settings. + +For reusable stacks, you probably want to put this configuration in a separate +`compose.mailrelay.yml` file, e.g. [the version in +`compose-stacks/nextcloud`][nextcloud-compose]. + +[`boky-postfix`]: https://hub.docker.com/r/boky/postfix +[boky-postfix-options]: https://github.com/bokysan/docker-postfix#postfix-specific-options [`abra`]: https://git.autonomic.zone/autonomic-cooperative/abra [`compose-stacks/traefik`]: https://git.autonomic.zone/compose-stacks/traefik +[nextcloud-compose]: https://git.autonomic.zone/compose-stacks/nextcloud/src/branch/main/compose.mailrelay.yml diff --git a/compose.yml b/compose.yml index 81fcc49..2dd776f 100644 --- a/compose.yml +++ b/compose.yml @@ -3,27 +3,41 @@ version: "3.8" services: app: - image: nginx:1.19.2 + image: "boky/postfix" networks: + - mail - proxy + healthcheck: + test: [ "CMD", "sh", "-c", "netstat -an | fgrep 587 | fgrep -q LISTEN" ] + interval: 10s + timeout: 5s + start_period: 10s + retries: 2 + environment: + FORCE_COLOR: "1" + TZ: ${TZ} + INBOUND_DEBUGGING: "${INBOUND_DEBUGGING:-0}" + ALLOWED_SENDER_DOMAINS: "${EXTRA_SENDER_DOMAINS} ${DOMAIN}" + POSTFIX_myhostname: "${DOMAIN}" deploy: restart_policy: condition: on-failure labels: - "traefik.enable=true" - "traefik.docker.network=proxy" - - "traefik.http.routers.${STACK_NAME}.tls=true" - - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80" - - "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`)" - - "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}" - - "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure" - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 1m + - "traefik.tcp.routers.${STACK_NAME}.entrypoints=smtp-submission" + - "traefik.tcp.routers.${STACK_NAME}.rule=HostSNI(`*`)" + # TODO 3wc: we can only route TCP traffic if it uses TLS + # https://doc.traefik.io/traefik/v2.0/routing/routers/#rule_1 + #- "traefik.tcp.routers.${STACK_NAME}.rule=HostSNI(`${DOMAIN}`)" + - "traefik.tcp.routers.${STACK_NAME}.service=${STACK_NAME}" + - "traefik.tcp.services.${STACK_NAME}.loadbalancer.server.port=587" + #- "traefik.tcp.routers.${STACK_NAME}.tls.passthrough=true" + #- "traefik.tcp.routers.${STACK_NAME}.tls=true" + #- "traefik.tcp.routers.${STACK_NAME}.service=mailu_smtp" networks: + mail: + external: true proxy: external: true