feat(dev-deploy): relay Mailpit to Gmail (Stage 3)
Keep Mailpit as the backend's SMTP submission point and turn on its relay so OTP/notification mail addressed to the owner reaches a real Gmail inbox, while everything else stays captured-only. - mailpit gains --smtp-relay-config + --smtp-relay-matching (default non-routable, so an unconfigured stack only captures); relay.conf is mounted from a new galaxy-dev-mailpit-config volume - tools/dev-deploy/mailpit/relay.conf.tmpl + a dev-deploy.yaml step that renders it from Gitea secrets (Gmail App Password, never committed) and seeds the volume; the GALAXY_DEV_MAIL_RELAY_MATCH var drives the relay-matching recipient - backend SMTP config unchanged (still -> galaxy-mailpit:1025) - dev-deploy README documents the relay + required secrets/vars Verified locally: compose config valid; the rendered relay.conf is accepted by mailpit v1.21.8 (relay + recipient-matching enabled). Real Gmail delivery is verified at the dev-deploy preview once the owner sets the secrets.
This commit is contained in:
@@ -117,13 +117,37 @@ and the dev-deploy compose ships with it enabled by default:
|
||||
1. Enter your email address in the login form.
|
||||
2. Submit `123456` as the code — the docker-compose default for
|
||||
`BACKEND_AUTH_DEV_FIXED_CODE` is `123456`, so the bcrypt-hashed
|
||||
email code stays a fallback. To force real Mailpit codes (e.g. for
|
||||
mail-flow QA), set `BACKEND_AUTH_DEV_FIXED_CODE=` (empty) in a
|
||||
local `.env` and `make rebuild`.
|
||||
email code stays a fallback. To force the real email code (which
|
||||
Mailpit then relays to your Gmail — see **Mail** below), set
|
||||
`BACKEND_AUTH_DEV_FIXED_CODE=` (empty) and redeploy.
|
||||
|
||||
The fixed-code override is rejected by production env loaders, so it
|
||||
cannot leak into the prod environment.
|
||||
|
||||
## Mail
|
||||
|
||||
The backend always submits mail to **Mailpit** (`galaxy-mailpit:1025`),
|
||||
exactly as it would to a production SMTP server. Mailpit captures every
|
||||
message in its UI (internal `:8025`) and, when configured, **relays**
|
||||
the ones whose recipient matches `GALAXY_DEV_MAIL_RELAY_MATCH` up to a
|
||||
real Gmail account — so an OTP addressed to you lands in your real inbox
|
||||
while everything else stays captured-only.
|
||||
|
||||
Configure the relay through Gitea Actions secrets/vars (never
|
||||
committed); the `dev-deploy.yaml` workflow renders Mailpit's
|
||||
`relay.conf` (from `tools/dev-deploy/mailpit/relay.conf.tmpl`) and seeds
|
||||
it into the `galaxy-dev-mailpit-config` volume:
|
||||
|
||||
| Name | Kind | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `GALAXY_DEV_MAIL_RELAY_USERNAME` | secret | Gmail address used as the relay login + From. |
|
||||
| `GALAXY_DEV_MAIL_RELAY_PASSWORD` | secret | Gmail **App Password** (requires 2FA; not the account password). |
|
||||
| `GALAXY_DEV_MAIL_RELAY_MATCH` | var | Recipient regex to auto-relay (e.g. your Gmail address). Unset → capture-only. |
|
||||
|
||||
With none set the stack only captures mail (the compose relay-match
|
||||
defaults to a non-routable address), so it can never email third
|
||||
parties.
|
||||
|
||||
## Networking
|
||||
|
||||
```
|
||||
|
||||
@@ -66,10 +66,20 @@ services:
|
||||
image: axllent/mailpit:v1.21
|
||||
container_name: galaxy-dev-mailpit
|
||||
restart: unless-stopped
|
||||
# Mailpit is both the SMTP submission point and a relay: it captures
|
||||
# every message in its UI and auto-relays the ones whose recipient
|
||||
# matches GALAXY_DEV_MAIL_RELAY_MATCH to the Gmail account in the
|
||||
# secret-rendered relay config. The default match is non-routable, so
|
||||
# a stack brought up without the relay secret only captures, never sends.
|
||||
command:
|
||||
- "--smtp-relay-config=/etc/mailpit/relay.conf"
|
||||
- "--smtp-relay-matching=${GALAXY_DEV_MAIL_RELAY_MATCH:-nobody@invalid.example}"
|
||||
labels:
|
||||
galaxy.stack: dev-deploy
|
||||
networks:
|
||||
- galaxy-internal
|
||||
volumes:
|
||||
- galaxy-dev-mailpit-config:/etc/mailpit:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "-O-", "http://localhost:8025/livez"]
|
||||
interval: 3s
|
||||
@@ -283,3 +293,5 @@ volumes:
|
||||
name: galaxy-dev-site-dist
|
||||
galaxy-dev-geoip-data:
|
||||
name: galaxy-dev-geoip-data
|
||||
galaxy-dev-mailpit-config:
|
||||
name: galaxy-dev-mailpit-config
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Mailpit SMTP relay upstream — RENDERED AT DEPLOY TIME by
|
||||
# .gitea/workflows/dev-deploy.yaml from Gitea Actions secrets, then
|
||||
# seeded into the `galaxy-dev-mailpit-config` volume. The Gmail App
|
||||
# Password is a secret and MUST NOT be committed: this template only
|
||||
# carries ${PLACEHOLDER}s that the workflow substitutes. See
|
||||
# tools/dev-deploy/README.md ("Mail").
|
||||
#
|
||||
# Mailpit captures every message; the `--smtp-relay-matching` flag (set
|
||||
# from GALAXY_DEV_MAIL_RELAY_MATCH in the compose) decides which
|
||||
# recipients are actually relayed up to this Gmail account.
|
||||
host: smtp.gmail.com
|
||||
port: 587
|
||||
starttls: true
|
||||
allow-insecure: false
|
||||
auth: login
|
||||
username: ${GALAXY_DEV_MAIL_RELAY_USERNAME}
|
||||
password: ${GALAXY_DEV_MAIL_RELAY_PASSWORD}
|
||||
return-path: ${GALAXY_DEV_MAIL_RELAY_USERNAME}
|
||||
Reference in New Issue
Block a user