Files
familienarchiv/docs/mail.md
Marcel 88e3fb32b3
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
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 <noreply@anthropic.com>
2026-03-23 09:20:43 +01:00

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=