From 88e3fb32b3e322477472760271ac0a1b48056c8e Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 23 Mar 2026 09:20:43 +0100 Subject: [PATCH] docs: add mail configuration guide Covers dev (Mailpit), production SMTP, all env vars with defaults, common provider settings, and how to disable mail entirely. Co-Authored-By: Claude Sonnet 4.6 --- docs/mail.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 docs/mail.md diff --git a/docs/mail.md b/docs/mail.md new file mode 100644 index 00000000..9d84b3cb --- /dev/null +++ b/docs/mail.md @@ -0,0 +1,96 @@ +# Mail configuration + +Familienarchiv uses Spring Mail to send password reset emails. The mail sender is **optional** — if no SMTP host is configured, the feature degrades gracefully: a reset token is still created in the database, but no email is sent and a warning is logged. + +## How it works in each environment + +| Environment | Default behaviour | +|---|---| +| `docker-compose up` (dev) | Mailpit catches all emails — nothing leaves your machine | +| CI | No mail host set — emails are silently skipped, tokens tested via the `/api/auth/reset-token-for-test` endpoint | +| Production | Real SMTP server configured via environment variables | + +--- + +## Development — Mailpit + +[Mailpit](https://github.com/axllent/mailpit) is included in `docker-compose.yml` as a local mail catcher. It accepts SMTP connections from the backend and displays all caught emails in a web inbox. No credentials or external network access required. + +**Start the stack as usual:** + +```bash +docker-compose up -d +``` + +**Open the inbox:** + +``` +http://localhost:8025 +``` + +All password reset emails appear here. Copy the reset link from the email body and open it in your browser to complete the flow end-to-end locally. + +**Ports (configurable in `.env`):** + +| Variable | Default | Purpose | +|---|---|---| +| `PORT_MAILPIT_UI` | `8025` | Mailpit web inbox | +| `PORT_MAILPIT_SMTP` | `1025` | SMTP port (used internally by the backend) | + +--- + +## Production — real SMTP + +To send real emails, set the following variables in your `.env` file (or as host environment variables). The `MAIL_HOST` variable is the switch — leaving it empty disables outgoing mail entirely. + +```dotenv +# Required +APP_BASE_URL=https://your-domain.example.com # Base URL inserted into reset links +MAIL_HOST=smtp.example.com +MAIL_PORT=587 +MAIL_USERNAME=your-smtp-user +MAIL_PASSWORD=your-smtp-password + +# Optional — adjust if your provider uses different settings +MAIL_SMTP_AUTH=true # default: false (Mailpit needs false) +MAIL_STARTTLS_ENABLE=true # default: false (Mailpit needs false) +APP_MAIL_FROM=noreply@your-domain.example.com +``` + +**Common provider settings:** + +| Provider | Host | Port | Auth | STARTTLS | +|---|---|---|---|---| +| Gmail (App Password) | `smtp.gmail.com` | `587` | `true` | `true` | +| Mailgun | `smtp.mailgun.org` | `587` | `true` | `true` | +| Hetzner | `mail.your-server.de` | `587` | `true` | `true` | +| Self-hosted Postfix | your server IP/hostname | `587` | `true` | `true` | + +> **Gmail note:** You must use an [App Password](https://support.google.com/accounts/answer/185833), not your regular account password. 2-Step Verification must be enabled on the account. + +--- + +## Environment variable reference + +All variables have safe defaults so the app starts without any mail configuration. + +| Variable | Default (docker-compose) | Description | +|---|---|---| +| `MAIL_HOST` | `mailpit` | SMTP hostname. Empty string disables mail entirely. | +| `MAIL_PORT` | `1025` | SMTP port. | +| `MAIL_USERNAME` | *(empty)* | SMTP username. Leave empty if your server needs no auth. | +| `MAIL_PASSWORD` | *(empty)* | SMTP password. | +| `MAIL_SMTP_AUTH` | `false` | Enable SMTP authentication (`true` for real servers). | +| `MAIL_STARTTLS_ENABLE` | `false` | Enable STARTTLS (`true` for real servers on port 587). | +| `APP_MAIL_FROM` | `noreply@familienarchiv.local` | The `From:` address on outgoing emails. | +| `APP_BASE_URL` | `http://localhost:3000` | Base URL prepended to password reset links. | + +--- + +## Disabling mail entirely + +Set `MAIL_HOST` to an empty string. Spring Boot will not create a mail sender bean and no emails will be sent. Password reset tokens are still written to the database — useful if you want to test the reset flow via the API directly. + +```dotenv +MAIL_HOST= +```