Port mail provisioning from the archived app repo (+ mesh-listener knobs) (#4)
This commit is contained in:
parent
8f98bab89f
commit
5fd96552f7
3 changed files with 61 additions and 9 deletions
|
|
@ -61,11 +61,45 @@ apt-get install -y -qq postfix libsasl2-modules
|
||||||
echo "==> configuring send-only null client"
|
echo "==> configuring send-only null client"
|
||||||
postconf -e "myhostname = ${MAIL_HOSTNAME}"
|
postconf -e "myhostname = ${MAIL_HOSTNAME}"
|
||||||
postconf -e "myorigin = ${MAIL_DOMAIN}"
|
postconf -e "myorigin = ${MAIL_DOMAIN}"
|
||||||
# THE important line: never listen on a public interface. This box sends only.
|
# Never listen on a public interface. This box sends only. The app runs in a
|
||||||
postconf -e "inet_interfaces = loopback-only"
|
# Docker container, so it can't reach the host's loopback — it hands mail to
|
||||||
|
# Postfix over the compose bridge's gateway. So Postfix also listens on that
|
||||||
|
# gateway and accepts mail from the bridge subnet (both pinned in
|
||||||
|
# docker-compose.yml). Set DOCKER_MAIL_GATEWAY="" for a pure loopback-only null
|
||||||
|
# client (app running natively on the host, not in a container).
|
||||||
|
DOCKER_MAIL_GATEWAY="${DOCKER_MAIL_GATEWAY-172.19.0.1}"
|
||||||
|
DOCKER_MAIL_SUBNET="${DOCKER_MAIL_SUBNET-172.19.0.0/16}"
|
||||||
|
# Optional WireGuard-mesh listener: other mesh nodes (e.g. beta's Forgejo, whose
|
||||||
|
# mailer posts to 10.10.0.1:25 — see deploy/forgejo/docker-stack.yml) can relay
|
||||||
|
# through this box. Prod runs with MESH_MAIL_LISTEN=10.10.0.1 and
|
||||||
|
# MESH_MAIL_PEERS=10.10.0.2/32; both default OFF so a plain run stays a strict
|
||||||
|
# null client. Without these, re-running this script on prod would silently drop
|
||||||
|
# the mesh listener and break Forgejo's outbound mail — the live config was
|
||||||
|
# originally hand-applied and this script is the source of truth for it now.
|
||||||
|
MESH_MAIL_LISTEN="${MESH_MAIL_LISTEN-}"
|
||||||
|
MESH_MAIL_PEERS="${MESH_MAIL_PEERS-}"
|
||||||
postconf -e "inet_protocols = ipv4"
|
postconf -e "inet_protocols = ipv4"
|
||||||
# Accept mail only from this machine.
|
listen="127.0.0.1"
|
||||||
postconf -e "mynetworks = 127.0.0.0/8 [::1]/128"
|
networks="127.0.0.0/8 [::1]/128"
|
||||||
|
if [[ -n "$DOCKER_MAIL_GATEWAY" ]]; then
|
||||||
|
listen="${listen}, ${DOCKER_MAIL_GATEWAY}"
|
||||||
|
networks="${networks} ${DOCKER_MAIL_SUBNET}"
|
||||||
|
# ufw is default-deny incoming; a container connecting to the host's gateway IP
|
||||||
|
# hits the INPUT chain, so allow the bridge subnet to reach port 25.
|
||||||
|
command -v ufw >/dev/null 2>&1 && \
|
||||||
|
ufw allow from "${DOCKER_MAIL_SUBNET}" to any port 25 proto tcp \
|
||||||
|
comment 'app container -> host Postfix' || true
|
||||||
|
fi
|
||||||
|
if [[ -n "$MESH_MAIL_LISTEN" ]]; then
|
||||||
|
listen="${listen}, ${MESH_MAIL_LISTEN}"
|
||||||
|
networks="${networks} ${MESH_MAIL_PEERS}"
|
||||||
|
fi
|
||||||
|
if [[ "$listen" == "127.0.0.1" ]]; then
|
||||||
|
postconf -e "inet_interfaces = loopback-only"
|
||||||
|
else
|
||||||
|
postconf -e "inet_interfaces = ${listen}"
|
||||||
|
fi
|
||||||
|
postconf -e "mynetworks = ${networks}"
|
||||||
# A null client delivers nothing locally; everything is relayed out.
|
# A null client delivers nothing locally; everything is relayed out.
|
||||||
postconf -e "mydestination ="
|
postconf -e "mydestination ="
|
||||||
postconf -e "local_transport = error:local delivery is disabled"
|
postconf -e "local_transport = error:local delivery is disabled"
|
||||||
|
|
|
||||||
|
|
@ -126,16 +126,20 @@ THERMOGRAPH_BASE_URL=https://thermograph.org
|
||||||
#THERMOGRAPH_VAPID_CONTACT=mailto:you@example.com
|
#THERMOGRAPH_VAPID_CONTACT=mailto:you@example.com
|
||||||
|
|
||||||
# --- Outbound email --------------------------------------------------------------
|
# --- Outbound email --------------------------------------------------------------
|
||||||
# Delivery goes through a local Postfix null client on 127.0.0.1:25 — see
|
# Delivery goes through the host's Postfix null client (deploy/provision-mail.sh).
|
||||||
# deploy/provision-mail.sh. The app only ever speaks plain SMTP to loopback, so
|
# The app runs in a container, so it can't reach the host's loopback — it speaks
|
||||||
# switching between "direct to MX" and "relay through a provider" is a Postfix
|
# plain SMTP to the compose bridge's gateway (172.19.0.1, pinned in
|
||||||
# config change and needs no code change or redeploy.
|
# docker-compose.yml), where Postfix listens and relays out. Switching between
|
||||||
|
# "direct to MX" and "relay through a provider" is a Postfix change, no redeploy.
|
||||||
#
|
#
|
||||||
# Backends: console (log it, send nothing — the default, right for dev),
|
# Backends: console (log it, send nothing — the default, right for dev),
|
||||||
# smtp (actually send), disabled (drop silently).
|
# smtp (actually send), disabled (drop silently).
|
||||||
# Leave unset until Postfix is provisioned: signups are still collected either way.
|
# Leave unset until Postfix is provisioned: signups are still collected either way.
|
||||||
|
# THERMOGRAPH_MAIL_FROM is left unset here on purpose — the app default
|
||||||
|
# (Thermograph <no-reply@thermograph.org>) is correct, and its "<>" would need
|
||||||
|
# escaping in this shell-sourced file. Override only if the address differs.
|
||||||
#THERMOGRAPH_MAIL_BACKEND=smtp
|
#THERMOGRAPH_MAIL_BACKEND=smtp
|
||||||
#THERMOGRAPH_SMTP_HOST=127.0.0.1
|
#THERMOGRAPH_SMTP_HOST=172.19.0.1
|
||||||
#THERMOGRAPH_SMTP_PORT=25
|
#THERMOGRAPH_SMTP_PORT=25
|
||||||
# Only needed if talking to a remote SMTP server directly instead of local Postfix.
|
# Only needed if talking to a remote SMTP server directly instead of local Postfix.
|
||||||
#THERMOGRAPH_SMTP_USER=
|
#THERMOGRAPH_SMTP_USER=
|
||||||
|
|
|
||||||
|
|
@ -180,3 +180,17 @@ volumes:
|
||||||
pgdata: {}
|
pgdata: {}
|
||||||
appdata: {}
|
appdata: {}
|
||||||
applogs: {}
|
applogs: {}
|
||||||
|
|
||||||
|
networks:
|
||||||
|
# Pin the default network's subnet + gateway so the host Postfix can rely on a
|
||||||
|
# stable address. The app sends verification email by speaking SMTP to the
|
||||||
|
# gateway (172.19.0.1), where the host Postfix listens and relays out (see
|
||||||
|
# deploy/provision-mail.sh + THERMOGRAPH_SMTP_HOST in thermograph.env). Without
|
||||||
|
# the pin, Docker picks a subnet from its pool and the gateway could move.
|
||||||
|
# 172.19.0.0/16 matches what prod and beta are live on today, so applying this
|
||||||
|
# is a no-op there.
|
||||||
|
default:
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.19.0.0/16
|
||||||
|
gateway: 172.19.0.1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue