Configuration and security
Fahrtenbuch is configured in two places:
.envfor everything the server needs at start: database, secrets, public address, sign-in methods, SMTP, Google/Microsoft sign-in and feature switches. Changes need a container restart (docker compose up -d).- Administration in the web dashboard for everything that can change at runtime: defaults, users, geocoding and map matching, AI providers, Gravatar, background jobs and the system backup.
The environment template is the complete reference for all variables.
Security basics
- Use strong, independent values for
POSTGRES_PASSWORD,JWT_SECRETandTOTP_ENCRYPTION_KEY, and replace the initial administrator password. TOTP_ENCRYPTION_KEYalso encrypts stored API keys (Dawarich, AI providers). If you change it, these keys have to be entered again.- Run the server behind an HTTPS reverse proxy and set
PUBLIC_BASE_URL,CORS_ORIGINandTRUST_PROXY=true. - Keep PostgreSQL, Redis and Redis Insight away from public access.
Public address and passkeys
| Variable | Purpose |
|---|---|
PUBLIC_BASE_URL | Public HTTPS address without trailing slash. Used for links in e-mails, sharing links, the QR code for the app and OAuth redirects. |
CORS_ORIGIN | Usually the same as PUBLIC_BASE_URL. |
WEBAUTHN_RP_ID | Hostname passkeys are bound to, e.g. fahrtenbuch.example.de. |
WEBAUTHN_ORIGIN | Origin of the web dashboard, e.g. https://fahrtenbuch.example.de. |
The setup assistant and Administration › Overview and system show whether these values are consistent.
Sign-in methods
| Variable | Default | Effect |
|---|---|---|
TOTP_ENABLED | true | false disables two-factor authentication server-wide. Stored secrets are kept and work again when re-enabled. |
PASSKEYS_ENABLED | true | false disables passkeys server-wide. Stored passkeys are kept. |
Clients ask the server which methods are offered (GET /auth/methods) and hide the others.
Sign in with Google and Microsoft
Users can sign in with a Google or Microsoft account they have linked in their profile. This never creates accounts.
| Variable | Purpose |
|---|---|
GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET | Enables Google. |
MICROSOFT_OAUTH_CLIENT_ID, MICROSOFT_OAUTH_CLIENT_SECRET | Enables Microsoft. |
MICROSOFT_OAUTH_TENANT | common (default), organizations, consumers or a tenant ID. |
OAUTH_APP_REDIRECT_URIS | Allowed redirects of the mobile app, default fahrtenbuch://oauth/callback. |
A provider is enabled when its client ID and secret are set. Register this redirect URI with the provider:
<PUBLIC_BASE_URL>/api/v1/auth/oauth/google/callback
<PUBLIC_BASE_URL>/api/v1/auth/oauth/microsoft/callback
Passkeys in the Android app
Passkeys are bound to the domain in WEBAUTHN_RP_ID. For the Android app to use the same passkeys as the web dashboard, Android must be able to verify that the app belongs to that domain, and the server must accept the app's origin.
The official app from Google Play works out of the box: its signing certificate fingerprint is built into the server, so /.well-known/assetlinks.json lists it and passkeys created in the app are accepted without any configuration. The variables below are only needed for other builds or apps.
| Variable | Default | Effect |
|---|---|---|
ANDROID_OFFICIAL_APP_ENABLED | true | false removes the built-in official app from the asset links file and the accepted origins. |
ANDROID_APP_CERT_SHA256 | – | Additional SHA-256 fingerprints for ANDROID_APP_PACKAGE, comma-separated (AB:CD:…), e.g. for self-built debug APKs. |
ANDROID_APP_PACKAGE | app.fahrtenbuch.mobile | Package the fingerprints in ANDROID_APP_CERT_SHA256 belong to. |
ANDROID_EXTRA_APPS | – | Further apps (e.g. forks) as package=FP|FP; package2=FP. |
Every listed fingerprint is also accepted as android:apk-key-hash:… origin for passkey registration and sign-in. Get the fingerprint of your own signing key with keytool -list -v -keystore … or ./gradlew signingReport. https://<WEBAUTHN_RP_ID>/.well-known/assetlinks.json must be publicly reachable over HTTPS without redirects – password managers such as Bitwarden verify it through Google's Digital Asset Links service. If a reverse proxy serves the domain, forward /.well-known/assetlinks.json to Fahrtenbuch.
Password reset
The server does not send password-reset e-mails itself. When a user requests a reset, it calls a webhook with the e-mail address and the reset link, for example an automation that sends the mail.
| Variable | Default | Purpose |
|---|---|---|
PASSWORD_RESET_WEBHOOK_URL | – | Receives POST with JSON { email, token, resetUrl, expiresAt }. Without it, no reset link is delivered. |
PASSWORD_RESET_URL | <PUBLIC_BASE_URL>/password-reset | Page the link points to. |
PASSWORD_RESET_EXPIRES_MINUTES | 30 | Validity of the link (5–1440). |
Without a webhook, an administrator sets a new password in Administration › User management and can force a change at the next sign-in.
E-mail (SMTP)
SMTP is used for vehicle sharing invitations and the monthly report. It is configured only in .env; without SMTP_HOST and SMTP_FROM all e-mail features are hidden.
| Variable | Example |
|---|---|
SMTP_HOST, SMTP_PORT, SMTP_SECURE | mail.example.de, 587, false |
SMTP_USER, SMTP_PASSWORD | credentials of the mailbox |
SMTP_FROM, SMTP_FROM_NAME | fahrtenbuch@example.de, Fahrtenbuch |
Administration › E-mail shows the detected configuration and sends a test e-mail.
Gravatar
Gravatar profile pictures are switched on or off under Administration › Overview and system (Allow Gravatar profile pictures). Until that has been saved once, the default comes from GRAVATAR_ENABLED (default true).
When Gravatar is disabled, clients receive gravatarAvailable: false, do not load any Gravatar image, and Gravatar is removed from the Content Security Policy. Users can additionally switch it off for themselves. Mention Gravatar in the privacy notice of your installation if it stays enabled: the browser or app sends a SHA-256 hash of the e-mail address and its IP address to Gravatar (Automattic Inc.).
Preview features
Some features are only enabled in the :dev image while they are being tested. Override them in .env:
| Variable | :dev | :latest | Feature |
|---|---|---|---|
FEATURE_EXPENSES | on | off | Vehicle costs |
FEATURE_MONTHLY_REPORT_SEND_NOW | on | off | Send by e-mail now on the monthly report page |
Disabled features are hidden in the web app; the API answers 404 FEATURE_DISABLED. Clients read the active features from GET /config/services.
Administration
| Tab | Contents |
|---|---|
| Overview and system | Status, version, central defaults (minimum distance and interval for tracking, pairing validity, default map position), map provider (OpenStreetMap raster tiles or your own Protomaps tile server, proxied by the backend), default language, Gravatar. |
| Detected SMTP configuration and test e-mail. | |
| User management | Create, edit, disable and delete users; set a password and force a change at the next sign-in; require or remove TOTP; allow or block passkeys; sign out sessions. |
| Geocoding | Address search, map matching and Dawarich Atlas – see geocoding and map matching. |
| AI | AI providers – see below. |
| Background jobs | Redis queues, failed jobs, reverse geocoding and map matching runs, Redis Insight. |
| Backup & restore | System-wide backup – see backups. |
Setup assistant
On the first administrator sign-in of a new installation, a setup assistant walks through: language, your own administrator password, server status (public address, passkeys, time zone), e-mail, geocoding, sign-in & privacy, a first vehicle (optional) and pairing the Android app. Settings that live in .env (SMTP, OAuth, public address) are only shown as status there.
Users created by an administrator get a first sign-in assistant.
AI providers
Administration › AI stores the connection to Claude (Anthropic), OpenAI (or any OpenAI-compatible server such as LM Studio, vLLM or LiteLLM) and your own Ollama server: address, API key and model per provider. One provider can be active, or none. Test connection checks the provider and lists its models.
API keys are stored encrypted and never returned by the API – only whether one is set and its last four characters. No feature uses AI yet; this is the groundwork for later features. Once a feature uses AI, the relevant data is sent to the selected provider; with Ollama it stays on your own server.
Further options
| Variable | Purpose |
|---|---|
SHOW_API_UI | true enables Swagger UI at /api and /api/docs. |
REDIS_INSIGHT_BIND_IP, REDIS_INSIGHT_PORT | Redis Insight listens on 127.0.0.1:5540 by default, because it has no login of its own. |
REDIS_INSIGHT_URL | Address shown as link in Background jobs, e.g. behind a reverse proxy with authentication. |
OSM_TILE_CACHE_MAX_BYTES | Size of the OpenStreetMap tile cache (default 10 GiB). |
TZ | Server time zone; users and trips have their own time zones. |