Files
TREK/wiki/Environment-Variables.md
Julien G. 002ea91be8 Align dev (#869)
* chore: bump version to 3.0.0 [skip ci]

* fix: resolve dead wiki links across install and config pages

* fix(reservations): restore correct day assignment for non-transport bookings

v3.0.0 switched the planner from rendering reservations by
reservation_time to rendering them by day_id (commit 3f61e1c), but
migration 110 only backfilled day_id for transport types. Tours,
restaurants, events and 'other' bookings kept whatever day_id was
stored in the DB — often the trip's first day, from older code paths
that defaulted it there — so after the upgrade those rows all show
up on day 1 regardless of their actual reservation_time.

- Migration 122: for every non-hotel reservation, null out any
  day_id / end_day_id that does not match the reservation's time,
  then backfill it from reservation_time / reservation_end_time.
  Idempotent; leaves already-correct rows alone.
- reservationService.createReservation / updateReservation now
  derive day_id / end_day_id from reservation_time /
  reservation_end_time when the client didn't send one explicitly,
  so the mismatch cannot reappear on new or edited bookings.
  Hotels are skipped because they store their date range on the
  linked day_accommodation.

* chore: bump version to 3.0.1 [skip ci]

* fix(oidc): normalize discovery doc issuer before comparison

Trailing slash in doc.issuer (e.g. Authentik) caused a mismatch against
the already-normalized configured issuer, breaking OIDC login entirely.

Closes #834

* test(systemNotices): exclude v3 upgrade notices from login_count-only tests

Tests that expect an empty notice list were using first_seen_version='0.0.0'
(DB default), which matches the existingUserBeforeVersion('3.0.0') condition
now that the app is at 3.0.1. Set first_seen_version='3.0.0' so only the
firstLogin condition controls visibility in these tests.

* chore: bump version to 3.0.2 [skip ci]

* fix(oidc): normalize id_token iss claim before issuer comparison (#837)

jwt.verify does an exact string match on the issuer. Providers like
Authentik include a trailing slash in the id_token iss claim while the
configured issuer is already normalized (no trailing slash), causing
every login attempt to fail with jwt issuer invalid.

Move the issuer check out of jwt.verify options and apply the same
trailing-slash normalization used in the discovery doc validation.
Also adds OIDC-SVC-033–036 unit tests covering exact match, trailing
slash, wrong issuer, and wrong audience cases.

Closes #834

* chore: bump version to 3.0.3 [skip ci]

* fix(oidc,ui): restore Authentik login and fix mobile delete dialog (#845)

OIDC: when OIDC_DISCOVERY_URL is explicitly set, trust the discovery
doc's issuer for id_token comparison instead of rejecting a path
mismatch as an error. Authentik (and similar realm-path providers)
return a canonical issuer like /application/o/<slug>/ that differs
from the operator's base OIDC_ISSUER. Strict equality blocked login
in 3.x despite working in v2. Default discovery (no custom URL) keeps
the strict check. Adds OIDC-SVC-037/038/039.

UI: ConfirmDialog and CopyTripDialog lacked the --bottom-nav-h
paddingBottom offset that other overlays already use. On mobile portrait
the action buttons were hidden behind the sticky bottom nav bar.

Closes #843
Closes #844

* chore: bump version to 3.0.4 [skip ci]

* fix(files): open attachments only in new tab (#840)

window.open with noreferrer returns null, which triggered the popup-blocked download fallback in addition to the new-tab open. Use a target=_blank anchor click instead.

* chore: bump version to 3.0.5 [skip ci]

* fix(journey,pdf): journey reorder sort_order + PDF multi-day transport (#848)

* fix(journey): make sort_order authoritative for within-day entry ordering

Reorder buttons appeared broken because the server ORDER BY put entry_time
before sort_order, so entries synced from trip places with differing times
would always sort by time regardless of sort_order writes. The client store
mirrored the same comparator, making even the optimistic update invisible.

- Change ORDER BY to (entry_date, sort_order, id) in getJourneyFull and listEntries
- Fix syncTripPlaces and onPlaceCreated to assign MAX+1 sort_order per day instead of day_number/0
- Update client store comparator to match
- Add DB migration to backfill sort_order using old effective key (entry_time, id) so existing journeys retain their visual order
- Add tests: JOURNEY-SVC-089–093, FE-STORE-JOURNEY-018–019

Closes #846

* fix(pdf): include multi-day transport return/arrival in PDF itinerary (#847)

Reservations were matched to days by pickup date only, so the end-day
card (e.g. car Return, flight Arrival) was silently dropped from the PDF.
Add span-aware helpers mirroring DayPlanSidebar logic: match by day_id/end_day_id
span, show reservation_end_time on end days, prefix title with phase label
(Return/Arrival/etc.), and use per-day position for sort order.

* test(pdf): add missing day_id to transport reservation fixture

* chore: bump version to 3.0.6 [skip ci]

* [Snyk] Security upgrade uuid from 9.0.1 to 14.0.0 (#849)

* fix: server/package.json & server/package-lock.json to reduce vulnerabilities

The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-UUID-16133035

* fix: bump fast-xml-parser version

---------

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
Co-authored-by: jubnl <jgunther021@gmail.com>

* chore: bump version to 3.0.7 [skip ci]

* fix: hot fixes 23-04-2026 (#856)

* fix(packing): resolve avatar URL path in bag and category assignees (#854)

packingService was returning raw avatar filenames from the DB instead of
the full /uploads/avatars/<filename> path, causing broken profile images
for users with uploaded avatars.

* fix(budget): use Map.get() to fix category rename no-op (#855)

* fix(security): relax Referrer-Policy and document HSTS_INCLUDE_SUBDOMAINS (#862) (#863)

- Change Helmet default from no-referrer to strict-origin-when-cross-origin
  so browsers send the origin on cross-origin requests, allowing Google Maps
  API key restrictions by HTTP referrer to work correctly
- Document HSTS_INCLUDE_SUBDOMAINS in all deployment artifacts:
  .env.example, docker-compose.yml, README.md, unraid-template.xml,
  charts/values.yaml, charts/configmap.yaml, wiki/Environment-Variables.md

* fix(planner): prefetch budget items on trip page mount (#864)

Loads budgetItems alongside reservations when TripPlannerPage mounts so
the Budget category dropdown in ReservationModal and TransportModal shows
pre-existing categories on first open, regardless of whether the Budget
tab has been visited.

Closes #861

* fix(reservations): prevent Invalid Date when end time is set without end date (#866)

When reservation_end_time held a bare time string ("HH:MM"), fmtDate()
produced Invalid Date on the reservation card.

- Modal: when end date is blank but end time is filled, construct a
  same-day ISO datetime using the start date (prevents time-only strings
  from ever being persisted)
- Panel: derive endDatePart via regex so date-only end values ("YYYY-MM-DD")
  still show the multi-day range, while bare time strings are skipped and
  handled correctly by the existing time column logic

Closes #860

* fix(planner): format reservation end time instead of rendering raw ISO string (#867)

Closes #859

* fix(planner): wire Route toggle into mobile day sidebar (#850) (#868)

The per-booking Route icon was missing on mobile because the mobile
DayPlanSidebar invocation in TripPlannerPage didn't pass
visibleConnectionIds or onToggleConnection. Mobile PWA users couldn't
activate reservation map overlays without forcing desktop mode.

Also corrects the Map-Features wiki: fixes the setting name
("Booking route labels" not "Show connection labels"), documents the
route_calculation requirement for travel-time pills, and explains that
overlays are off by default and must be toggled per reservation.

* chore: bump version to 3.0.8 [skip ci]

---------

Co-authored-by: Maurice <61554723+mauriceboe@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Maurice <mauriceboe@icloud.com>
Co-authored-by: Xre0uS <36565320+Xre0uS@users.noreply.github.com>
Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2026-04-23 19:57:50 +02:00

7.4 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
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
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.

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

Other

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