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 <noreply@anthropic.com>
3.7 KiB
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 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:
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.
# 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, 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.
MAIL_HOST=