Files
TREK/wiki/Environment-Variables.md
Maurice 247433fb2a feat(costs): rework Budget into Costs — Splitwise-style, multi-currency, mobile (#1106)
* fix(journey): authorize reads of the journey share link

GET /api/journeys/:id/share-link now requires journey access (canAccessJourney),
matching the create/delete share-link routes and the get_journey_share_link MCP
tool. Returns no link when the caller lacks access to the journey.

* feat(costs): rework Budget into Costs — Splitwise-style, multi-currency, mobile

Renames the Budget addon to "Costs" (UI only) and reworks it into a Tricount/
Splitwise-style cost tracker: multiple payers per expense, equal split across
chosen members, settle-up with persisted history + undo, 12 fixed categories,
per-expense currency with live FX conversion to a user-set display currency
(Settings -> Display), and locale-correct money formatting. Adds a desktop and a
dedicated mobile layout. A migration backfills existing budget items (single
payer, split members, currency). Closes #551 (per-expense currency).

Also switches the app font to self-hosted Poppins (Geist for secondary subtext),
replacing the Google Fonts CDN dependency.

* fix(costs): neutral dashboard dark palette + liquid glass, full page width, entry-count badge

- Dark mode used a warm oklch palette that read brownish; switch to the
  neutral zinc tokens used by the dashboard (#121215 bg, #f4f4f5 ink) and add a
  subtle backdrop-blur glass on cards.
- Costs now uses the full available page width on desktop instead of a 1280px cap.
- Render the expense count next to the Expenses title as a badge.
- Adapt budget/journey unit tests to the new payer-based settlement model and the
  Costs rename (category default 'other', Costs tab/CostsPanel).

* fix(costs): drop the entry-count badge, always show row edit/delete actions

Removes the count badge next to the Expenses title and makes the per-row
edit/delete actions permanently visible (no longer hover-only) on desktop too.

* feat(costs): currency-native money formatting, custom select/date, rename addon to Costs

- Format every amount in its own currency convention (symbol position, grouping
  and decimal separators) regardless of app language, via a currency->locale map
  (EUR -> '12,00 €', USD -> '$12.00', JPY -> '¥12', ...). Previously Intl used the
  app locale, so EUR showed the symbol in front under an English UI.
- Use TREK's CustomSelect (searchable, with symbols) and CustomDatePicker in the
  add/edit expense modal instead of the native <select>/<input type=date>.
- Rename the 'Budget Planner' add-on to 'Costs' in the admin list (display only;
  id/tables/permissions/MCP stay 'budget') via seed + a migration for existing DBs.

* feat(auth): configurable session duration via SESSION_DURATION

Adds a SESSION_DURATION env var (ms-style strings: 1h, 7d, 30d, ...) controlling
how long a session stays valid before re-login. It drives both the trek_session
JWT exp claim and the cookie maxAge from one source, so they never drift. Invalid
values warn at startup and fall back to the default (24h — unchanged). The MFA
challenge token and MCP OAuth tokens keep their own TTL.

Implements the request from discussion #946. Documented in the env-var wiki page,
.env.example and docker-compose.yml.
2026-06-05 01:38:25 +02:00

9.8 KiB

Environment Variables

Complete reference for all environment variables TREK reads.

How to Set Variables

  • Docker Compose — use the environment: block or a .env file alongside docker-compose.yml
  • Docker run — pass each variable with -e VARIABLE=value
  • Helm — use env: for plain values and secretEnv: for sensitive values in values.yaml
  • Unraid — set in the container template editor

Core

Variable Description Default
PORT Server port 3000
HOST Bind address for the HTTP server (e.g. 127.0.0.1, 10.0.0.72). Source / Proxmox installs only — do not set this in Docker or any containerized deployment. See note below. all interfaces
NODE_ENV Environment (production / development) production
ENCRYPTION_KEY At-rest encryption key — see resolution order below auto
TZ Timezone for logs, reminders, and cron jobs (e.g. Europe/Berlin) UTC
LOG_LEVEL info = concise user actions; debug = verbose details info
DEFAULT_LANGUAGE Default language on the login page — see supported codes below en
SESSION_DURATION How long a login session stays valid before re-login is required. Applies to both the trek_session JWT exp claim and the cookie maxAge, so they never drift apart. Accepts ms-style strings: 1h, 12h, 7d, 30d, 90d. Invalid values warn at startup and fall back to the default. Does not affect the short-lived MFA challenge token or MCP OAuth tokens (those keep their own TTL). 24h
ALLOWED_ORIGINS Comma-separated origins for CORS and email notification links same-origin
ALLOW_INTERNAL_NETWORK Allow outbound requests to private/RFC-1918 IPs. Set true if Immich or other integrated services are on your local network. Loopback (127.x) and link-local (169.254.x) addresses remain blocked regardless. false
APP_URL Public base URL (e.g. https://trek.example.com). Required when OIDC is enabled — must match the redirect URI registered with your IdP. Also used as the base URL for email notification links.

HOST — Source and Proxmox installs only

By default TREK binds to all network interfaces (0.0.0.0), which is the correct behaviour inside a container because Docker handles port exposure at the host level. Setting HOST overrides the bind address at the Node.js level.

When to use it: only when running TREK directly on a host (git sources or the Proxmox community script) and you need to restrict which interface the server listens on — for example, to expose TREK only on a LAN interface while keeping it off the public-facing one.

Never set HOST in Docker, Docker Compose, Helm, or Unraid deployments. Use Docker's -p <host-ip>:<host-port>:<container-port> syntax or your orchestrator's port binding instead.

# .env — source / Proxmox installs only
HOST=10.0.0.72   # bind only on this LAN interface
PORT=3001

When HOST is set, the startup banner includes a Host: line confirming the bound address.

ENCRYPTION_KEY — Resolution Order

server/src/config.ts resolves the encryption key in this order:

  1. ENCRYPTION_KEY env var — explicit value, always takes priority. Persisted to data/.encryption_key automatically.
  2. data/.encryption_key file — present on any install that has started at least once.
  3. data/.jwt_secret file — one-time fallback for existing installs upgrading without a pre-set key. The value is immediately persisted to data/.encryption_key so JWT rotation cannot break decryption later.
  4. Auto-generated — fresh install with none of the above; persisted to data/.encryption_key.

Setting ENCRYPTION_KEY explicitly is recommended so you can back it up independently of the data volume.

DEFAULT_LANGUAGE — Supported Codes

Verified in server/src/config.ts (line 107):

de, en, es, fr, hu, nl, br, cs, pl, ru, zh, zh-TW, it, ar

Note: id (Indonesian / Bahasa Indonesia) appears in client/src/i18n/supportedLanguages.ts but is not in the server's supported-codes list in config.ts. Setting DEFAULT_LANGUAGE=id will fall back to en with a warning in the server log.


HTTPS / Proxy

These three variables work together behind a TLS-terminating reverse proxy. See Reverse-Proxy for the full explanation.

Variable Description Default
FORCE_HTTPS When true: 301-redirects HTTP→HTTPS, sends HSTS (max-age=31536000), adds CSP upgrade-insecure-requests, forces cookie secure flag. Only useful behind a TLS proxy. Requires TRUST_PROXY. false
HSTS_INCLUDE_SUBDOMAINS When true: adds the includeSubDomains directive to the HSTS header, extending HTTPS enforcement to all subdomains. Only effective when HSTS is active (FORCE_HTTPS=true or NODE_ENV=production). Leave false if you run other services on sibling subdomains over plain HTTP. false
TRUST_PROXY Number of trusted proxy hops. Tells Express to read the real client IP from X-Forwarded-For and protocol from X-Forwarded-Proto. Defaults to 1 automatically in production. Required for FORCE_HTTPS to detect the forwarded protocol. 1 (production)
COOKIE_SECURE Controls the secure flag on the trek_session cookie. Auto-derived as true when NODE_ENV=production or FORCE_HTTPS=true. Set to false only as an escape hatch for LAN testing without TLS — not recommended in production. auto

Warning: FORCE_HTTPS=true without TRUST_PROXY set causes a redirect loop.


OIDC / SSO

For setup instructions, see OIDC-SSO.

Variable Description Default
OIDC_ISSUER OpenID Connect provider URL (e.g. https://auth.example.com)
OIDC_CLIENT_ID OIDC client ID
OIDC_CLIENT_SECRET OIDC client secret
OIDC_DISPLAY_NAME Label shown on the SSO login button SSO
OIDC_ONLY Force SSO-only mode: disables password login and registration, overrides Admin > Settings toggles, cannot be changed at runtime. First SSO login becomes admin on a fresh instance. false
OIDC_ADMIN_CLAIM OIDC claim used to identify admin users (e.g. groups)
OIDC_ADMIN_VALUE Value of the OIDC claim that grants admin role (e.g. app-trek-admins)
OIDC_SCOPE Space-separated OIDC scopes to request. Fully replaces the default — always include openid email profile plus any extra scopes (e.g. add groups when using OIDC_ADMIN_CLAIM) openid email profile
OIDC_DISCOVERY_URL Override the auto-constructed OIDC discovery endpoint. Required for providers with a non-standard path (e.g. Authentik)

Email / SMTP

SMTP settings can be configured via the Admin panel or overridden with environment variables. Env vars take priority over the database values.

Variable Description Default
SMTP_HOST SMTP server hostname (e.g. smtp.example.com)
SMTP_PORT SMTP server port. Port 465 enables implicit TLS (secure: true); all other ports use STARTTLS or plain.
SMTP_USER SMTP authentication username
SMTP_PASS SMTP authentication password
SMTP_FROM Sender address for outbound emails (e.g. TREK <noreply@example.com>)
SMTP_SKIP_TLS_VERIFY Set true to disable TLS certificate validation. Useful for self-signed certs on internal SMTP relays — not recommended in production. false

SMTP_HOST, SMTP_PORT, and SMTP_FROM are all required for email delivery to work. SMTP_USER and SMTP_PASS are optional (for unauthenticated relays).


Initial Setup

These variables only take effect on first boot, before any user exists.

Variable Description Default
ADMIN_EMAIL Email for the first admin account admin@trek.local
ADMIN_PASSWORD Password for the first admin account random

Both variables must be set together. If either is omitted, the account is created with email admin@trek.local and a randomly generated password that is printed to the server log. Once any user exists, these variables have no effect.


MCP

For setup instructions, see MCP-Overview.

Variable Description Default
MCP_RATE_LIMIT Max MCP API requests per user per minute 300
MCP_MAX_SESSION_PER_USER Max concurrent MCP sessions per user 20

Booking Import (KDE Itinerary)

Variable Description Default
KITINERARY_EXTRACTOR_PATH Full path to the kitinerary-extractor binary. When unset, TREK searches /usr/lib/*/libexec/kf6/kitinerary-extractor and then PATH. Set this if you install the binary to a non-standard location. auto-detected

The official TREK Docker image bundles the binary automatically: on amd64 it downloads the static release from https://cdn.kde.org/ci-builds/pim/kitinerary/; on arm64 it installs libkitinerary-bin via apt (Debian trixie). When running TREK from source, install libkitinerary-bin (Debian trixie / Ubuntu 25.04+) or download the static binary directly and place it anywhere on PATH. The GET /api/health/features endpoint returns { "bookingImport": true } when the binary is found, and the Import button in the Reservations panel is hidden when it is not.


Other

Variable Description Default
DEMO_MODE Enable demo mode (hourly data resets). Not intended for regular use. false