# 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= ```