5.8 KiB
SMTP Configuration – Concept
Status: Implemented
Last updated: 2026-03-12
1. Goal
Enable configurable SMTP for sending transactional emails (join confirmation, user confirmation, password reset). Configuration via environment variables and Admin Settings (database), with the same precedence pattern as OIDC and Vereinfacht: ENV overrides Settings. Include a test email action in Settings (button + recipient field) with clear success/error feedback.
2. Scope
- In scope: SMTP server configuration (host, port, credentials, TLS/SSL), sender identity (from-name, from-email), test email from Settings UI, warning when SMTP is not configured in production, specific error messages per failure category, graceful delivery errors in AshAuthentication senders.
- Out of scope: Separate adapters per email type; retry queues.
3. Configuration Sources
| Source | Priority | Use case |
|---|---|---|
| ENV | 1 | Production, Docker, 12-factor |
| Settings | 2 | Admin UI, dev without ENV |
When an ENV variable is set, the corresponding Settings field is read-only in the UI (with hint "Set by environment").
4. SMTP Parameters
| Parameter | ENV | Settings attribute | Notes |
|---|---|---|---|
| Host | SMTP_HOST |
smtp_host |
e.g. smtp.example.com |
| Port | SMTP_PORT |
smtp_port |
Default 587 (TLS), 465 (SSL), 25 (plain) |
| Username | SMTP_USERNAME |
smtp_username |
Optional if no auth |
| Password | SMTP_PASSWORD |
smtp_password |
Sensitive, not shown when set |
| Password file | SMTP_PASSWORD_FILE |
— | Docker/Secrets: path to file with password |
| TLS/SSL | SMTP_SSL |
smtp_ssl |
tls / ssl / none (default: tls) |
| Sender name | MAIL_FROM_NAME |
smtp_from_name |
Display name in "From" header (default: Mila) |
| Sender email | MAIL_FROM_EMAIL |
smtp_from_email |
Address in "From" header; must match SMTP user on most servers |
Important: On most SMTP servers (e.g. Postfix with strict relay policies) the sender email (smtp_from_email) must be the same address as smtp_username or an alias that is owned by that account.
5. Password from File
Support SMTP_PASSWORD_FILE (path to file containing the password), same pattern as OIDC_CLIENT_SECRET_FILE in runtime.exs. Read once at runtime; SMTP_PASSWORD ENV overrides file if both are set.
6. Behaviour When SMTP Is Not Configured
- Dev/Test: Keep current adapters (
Swoosh.Adapters.Local,Swoosh.Adapters.Test). No change. - Production: If neither ENV nor Settings provide SMTP (no host):
- Show a warning in the Settings UI.
- Delivery attempts silently fall back to the Local adapter (no crash).
7. Test Email (Settings UI)
- Location: SMTP / E-Mail section in Global Settings.
- Elements: Input for recipient, submit button inside a
phx-submitform. - Behaviour: Sends one email using current SMTP config and
mail_from/0. Returns{:ok, _}or{:error, classified_reason}. - Error categories:
:sender_rejected,:auth_failed,:recipient_rejected,:tls_failed,:connection_failed,{:smtp_error, message}— each shows a specific human-readable message in the UI. - Permission: Reuses existing Settings page authorization (admin).
8. Sender Identity (mail_from)
Mv.Mailer.mail_from/0 returns {name, email}. Priority:
MAIL_FROM_NAME/MAIL_FROM_EMAILENV variablessmtp_from_name/smtp_from_emailin Settings (DB)- Hardcoded defaults:
{"Mila", "noreply@example.com"}
Provided by Mv.Config.mail_from_name/0 and Mv.Config.mail_from_email/0.
9. AshAuthentication Senders
Both SendPasswordResetEmail and SendNewUserConfirmationEmail use Mv.Mailer.deliver/1 (not deliver!/1). Delivery failures are logged (Logger.error) and not re-raised, so they never crash the caller process. AshAuthentication ignores the return value of send/3.
10. TLS / SSL in OTP 27
OTP 26+ enforces verify_peer by default, which fails for self-signed or internal SMTP server certificates.
Both tls_options: [verify: :verify_none] (for STARTTLS, port 587) and sockopts: [verify: :verify_none] (for direct SSL, port 465) are set in Mv.Mailer.smtp_config/0 to allow such certificates.
For ENV-based boot config, the same options are set in config/runtime.exs.
11. Summary Checklist
- ENV:
SMTP_HOST,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD,SMTP_PASSWORD_FILE,SMTP_SSL. - ENV:
MAIL_FROM_NAME,MAIL_FROM_EMAILfor sender identity. - Settings: attributes and UI for host, port, username, password, TLS/SSL, from-name, from-email.
- Password from file:
SMTP_PASSWORD_FILEsupported inruntime.exs. - Mailer: Swoosh SMTP adapter configured from merged ENV + Settings when SMTP is configured.
- Per-request SMTP config via
Mv.Mailer.smtp_config/0for Settings-only scenarios. - TLS certificate validation relaxed for OTP 27 (tls_options + sockopts).
- Prod warning: clear message in Settings when SMTP is not configured.
- Test email: form with recipient field, translatable content, classified success/error messages.
- AshAuthentication senders: graceful error handling (no crash on delivery failure).
- Gettext for all new UI strings, translated to German.
- Docs and code guidelines updated.