Initial commit: HTTP wrapper around the existing falah-ibaas email connector
Gives Supabase Edge Functions (and anything else outside the VPS) a real, authenticated endpoint onto the VPS's already-working internal Postfix relay (the same one Ghost uses in production), via the falah-ibaas EmailConnector that was fully built but never actually deployed. Deployed live at https://nfmailrelay.falahos.my as a Docker Swarm service on the existing Traefik network, TLS via Let's Encrypt, shared-secret bearer auth. Built for Nur Falah's heir notification emails.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# nf-mail-relay
|
||||
|
||||
Small HTTP wrapper around the existing `falah-ibaas` email connector
|
||||
(`/opt/falah-ibaas/connectors/email` on the Falah OS VPS), so services that
|
||||
can't reach the VPS's internal Postfix relay directly — like a Supabase Edge
|
||||
Function running on Supabase's cloud — get a real, internet-reachable,
|
||||
authenticated endpoint that forwards to it.
|
||||
|
||||
Built for Nur Falah's heir (warith) notification emails, but generic enough
|
||||
to reuse for anything else that needs "send an email via the VPS's existing
|
||||
working mail path" without provisioning a third-party provider.
|
||||
|
||||
## Why this exists
|
||||
|
||||
The VPS already has a working SMTP relay — Ghost uses it in production
|
||||
(`mail__options__host=172.17.0.1:25`, no auth, internal Docker bridge only).
|
||||
There's also a fully-built but never-deployed `EmailConnector` class at
|
||||
`/opt/falah-ibaas/connectors/email/handler.py` that wraps `smtplib` with
|
||||
proper error handling. Neither was reachable from outside the VPS. This
|
||||
relay is the missing piece: a thin, auth-gated HTTP front door onto that
|
||||
connector.
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `GET /health` — connector status + send/error metrics
|
||||
- `POST /send` — send an email
|
||||
- Header: `X-Relay-Secret: <shared secret>`
|
||||
- Body: `{ "to": "...", "subject": "...", "body_text": "...", "body_html": "...", "cc": "...", "bcc": "..." }`
|
||||
|
||||
## Deploy
|
||||
|
||||
```bash
|
||||
docker build -t nf-mail-relay:latest .
|
||||
|
||||
docker service create \
|
||||
--name nf_mail_relay \
|
||||
--mount type=bind,source=/opt/falah-ibaas/connectors/email,target=/opt/falah-ibaas/connectors/email,readonly \
|
||||
--network falah_traefik-net \
|
||||
--constraint node.role==manager \
|
||||
--env RELAY_SECRET=<generate with: openssl rand -hex 24> \
|
||||
--env SMTP_HOST=172.17.0.1 \
|
||||
--env SMTP_PORT=25 \
|
||||
--env SMTP_FROM=notifications@falahos.my \
|
||||
--label traefik.enable=true \
|
||||
--label 'traefik.http.routers.nfmailrelay.rule=Host(`nfmailrelay.falahos.my`)' \
|
||||
--label traefik.http.routers.nfmailrelay.entrypoints=websecure \
|
||||
--label traefik.http.routers.nfmailrelay.tls=true \
|
||||
--label traefik.http.routers.nfmailrelay.tls.certresolver=letsencrypt \
|
||||
--label traefik.http.services.nfmailrelay.loadbalancer.server.port=8091 \
|
||||
nf-mail-relay:latest
|
||||
```
|
||||
|
||||
Currently deployed at `https://nfmailrelay.falahos.my` on the Falah OS VPS
|
||||
(13.140.161.244), covered by the `*.falahos.my` wildcard DNS — no new DNS
|
||||
record needed.
|
||||
|
||||
## Security notes
|
||||
|
||||
- `RELAY_SECRET` is never committed here — it's set as a Docker service
|
||||
environment variable on deploy. Rotate with `docker service update
|
||||
--env-add RELAY_SECRET=<new value> nf_mail_relay`.
|
||||
- The connector directory is bind-mounted **read-only** — this service
|
||||
cannot modify `falah-ibaas`.
|
||||
- No auth is used against the Postfix relay itself since it's only bound to
|
||||
the internal Docker bridge (`172.17.0.1`) — this service is the actual
|
||||
security boundary between the public internet and that relay.
|
||||
Reference in New Issue
Block a user