2026-04-20 22:25:38 +08:00
< div align = "center" >
< picture >
< source media = "(prefers-color-scheme: dark)" srcset = "docs/logo-trek-light.gif" / >
< source media = "(prefers-color-scheme: light)" srcset = "docs/logo-trek-dark.gif" / >
< img src = "docs/logo-trek-dark.gif" alt = "TREK" height = "96" / >
< / picture >
### Your trips. Your plan. Your server.
A self-hosted, real-time collaborative travel planner — with maps, budgets, packing lists, a journal, and AI built in.
< br / >
< a href = "https://demo-nomad.pakulat.org" > < img alt = "Live Demo" src = "https://img.shields.io/badge/Live_Demo-try_it_now-111827?style=for-the-badge" / > < / a >
< a href = "https://hub.docker.com/r/mauriceboe/trek" > < img alt = "Docker" src = "https://img.shields.io/badge/Docker-ready-2496ED?style=for-the-badge&logo=docker&logoColor=white" / > < / a >
< a href = "https://discord.gg/NhZBDSd4qW" > < img alt = "Discord" src = "https://img.shields.io/badge/Discord-community-5865F2?style=for-the-badge&logo=discord&logoColor=white" / > < / a >
< a href = "https://kanban.pakulat.org/shared/I4wxF6inOOMB0C6hH6kQm3efyNxFjwyI" > < img alt = "Roadmap" src = "https://img.shields.io/badge/Roadmap-board-0EA5E9?style=for-the-badge&logo=trello&logoColor=white" / > < / a >
< br / >
< a href = "LICENSE" > < img alt = "License" src = "https://img.shields.io/badge/license-AGPL_v3-6B7280?style=flat-square" / > < / a >
< a href = "https://github.com/mauriceboe/TREK/releases" > < img alt = "Latest Release" src = "https://img.shields.io/github/v/release/mauriceboe/TREK?include_prereleases&style=flat-square&color=6B7280" / > < / a >
< a href = "https://hub.docker.com/r/mauriceboe/trek" > < img alt = "Docker Pulls" src = "https://img.shields.io/docker/pulls/mauriceboe/trek?style=flat-square&color=6B7280" / > < / a >
< a href = "https://github.com/mauriceboe/TREK" > < img alt = "Stars" src = "https://img.shields.io/github/stars/mauriceboe/TREK?style=flat-square&color=6B7280" / > < / a >
< / div >
---
< div align = "center" >
2026-04-20 23:15:48 +08:00
< img src = "https://github.com/mauriceboe/trek-media/releases/download/readme-assets/TREK1.gif" alt = "TREK — 60-second tour" width = "100%" / >
2026-04-20 22:25:38 +08:00
< / div >
< br / >
< div align = "center" >
< a href = "docs/screenshots/dashboard.png" > < img src = "docs/screenshots/dashboard.png" alt = "Dashboard" width = "49%" / > < / a >
< a href = "docs/screenshots/trip-planner.png" > < img src = "docs/screenshots/trip-planner.png" alt = "Trip planner with 3D map" width = "49%" / > < / a >
< a href = "docs/screenshots/journey.png" > < img src = "docs/screenshots/journey.png" alt = "Journey journal" width = "49%" / > < / a >
< a href = "docs/screenshots/budget.png" > < img src = "docs/screenshots/budget.png" alt = "Budget tracker" width = "49%" / > < / a >
< a href = "docs/screenshots/atlas.png" > < img src = "docs/screenshots/atlas.png" alt = "Atlas · visited countries" width = "49%" / > < / a >
< a href = "docs/screenshots/vacay.png" > < img src = "docs/screenshots/vacay.png" alt = "Vacay planner" width = "49%" / > < / a >
< a href = "docs/screenshots/trip-iceland.png" > < img src = "docs/screenshots/trip-iceland.png" alt = "Iceland Ring Road" width = "49%" / > < / a >
< a href = "docs/screenshots/admin.png" > < img src = "docs/screenshots/admin.png" alt = "Admin panel" width = "49%" / > < / a >
< / div >
---
## What you get
< picture >
< source media = "(max-width: 700px)" srcset = "docs/tiles/grid-mobile.svg" / >
< img src = "docs/tiles/grid-desktop.svg" alt = "TREK feature tiles" width = "100%" / >
< / picture >
2026-03-20 00:19:00 +08:00
2026-03-20 00:23:58 +08:00
< details >
2026-04-20 22:25:38 +08:00
< summary > < b > See all features< / b > < / summary >
2026-03-20 00:23:58 +08:00
2026-04-20 22:25:38 +08:00
< table >
< tr >
< td width = "50%" valign = "top" >
2026-03-20 00:23:58 +08:00
2026-04-20 22:25:38 +08:00
#### 🧭 Trip planning
2026-03-20 00:23:58 +08:00
2026-04-20 22:25:38 +08:00
- **Drag & drop planner** — organise places into day plans with reordering and cross-day moves
- **Interactive map** — Leaflet or Mapbox GL with 3D buildings, terrain, photo markers, clustering, route visualization
- **Place search** — Google Places (photos, ratings, hours) or OpenStreetMap (free, no API key)
- **Day notes** — timestamped, icon-tagged notes with drag-and-drop reordering
- **Route optimisation** — auto-sort places and export to Google Maps
- **Weather forecasts** — 16-day via Open-Meteo (no key) + historical climate fallback
- **Category filter** — show only matching pins on the map
< / td >
< td width = "50%" valign = "top" >
#### 🧳 Travel management
- **Reservations** — flights, accommodations, restaurants with status, confirmation numbers, files
- **Budget tracking** — category-based expenses with pie chart, per-person / per-day splits, multi-currency
- **Packing lists** — categories, templates, user assignment, progress tracking
- **Bag tracking** — optional weight tracking with iOS-style distribution
- **Document manager** — attach docs, tickets, PDFs to trips / places / reservations (≤ 50 MB each)
- **PDF export** — full trip plan as PDF with cover page, images, notes
< / td >
< / tr >
< tr >
< td width = "50%" valign = "top" >
#### 👥 Collaboration
2026-04-11 21:40:02 +08:00
2026-04-20 22:25:38 +08:00
- **Real-time sync** — WebSocket. Changes appear instantly across all connected users
- **Multi-user trips** — invite members with role-based access
- **Invite links** — one-time or reusable links with expiry
- **SSO (OIDC)** — Google, Apple, Authentik, Keycloak, or any OIDC provider
- **2FA** — TOTP + backup codes
- **Collab suite** — group chat, shared notes, polls, day check-ins
2026-04-11 21:40:02 +08:00
2026-04-20 22:25:38 +08:00
< / td >
< td width = "50%" valign = "top" >
#### 📱 Mobile & PWA
- **Installable** — iOS and Android, straight from the browser, no App Store needed
- **Offline support** — Service Worker caches tiles, API, uploads via Workbox
- **Native feel** — fullscreen standalone, themed status bar, splash screen
- **Touch optimised** — mobile-specific layouts with safe-area handling
< / td >
< / tr >
< tr >
< td width = "50%" valign = "top" >
#### 🧩 Addons (admin-toggleable)
- **Vacay** — personal vacation planner with calendar, 100+ country holidays, carry-over tracking
- **Atlas** — world map of visited countries, bucket list, travel stats, streak tracking, liquid-glass UI
- **Collab** — chat, notes, polls, day-by-day attendance
- **Journey** — magazine-style travel journal with entries, photos, maps, moods
- **Dashboard widgets** — currency converter and timezone clocks
< / td >
< td width = "50%" valign = "top" >
#### 🤖 AI / MCP
- **Built-in MCP server** — OAuth 2.1 authenticated. 80+ tools, 27 resources
- **Granular scopes** — 24 OAuth scopes across 13 permission groups
- **Full automation** — AI can create trips, plan days, build packing lists, manage budgets, mark countries visited
- **Pre-built prompts** — `trip-summary` , `packing-list` , `budget-overview`
- **Addon-aware** — exposes Atlas, Collab, Vacay when those addons are on
< / td >
< / tr >
< tr >
< td colspan = "2" valign = "top" >
#### ⚙️ Admin & customisation
- **Dashboard views** — card grid or compact list · **Dark mode** — full theme with matching status bar
- **14 languages** — EN, DE, ES, FR, IT, NL, HU, RU, ZH, ZH-TW, PL, CS, AR (RTL), BR, ID
- **Admin panel** — users, invites, packing templates, categories, addons, API keys, backups, GitHub history
- **Auto-backups** — scheduled with configurable retention · **Units** — °C/°F, 12h/24h, map tile sources, default coordinates
< / td >
< / tr >
< / table >
< / details >
< br / >
## Get started in 30 seconds
2026-03-19 06:58:08 +08:00
2026-03-19 07:21:57 +08:00
```bash
2026-04-01 15:35:32 +08:00
ENCRYPTION_KEY=$(openssl rand -hex 32) docker run -d -p 3000:3000 \
-e ENCRYPTION_KEY=$ENCRYPTION_KEY \
-v ./data:/app/data -v ./uploads:/app/uploads mauriceboe/trek
2026-03-19 07:21:57 +08:00
```
2026-03-19 06:58:08 +08:00
2026-04-20 22:25:38 +08:00
Open `http://localhost:3000` . The first user to register becomes admin.
< div align = "center" >
· < a href = "#docker-compose-production" > Docker Compose< / a > · < a href = "#helm-kubernetes" > Helm / Kubernetes< / a > · < a href = "#install-as-app-pwa" > Install as PWA< / a > · < a href = "#reverse-proxy" > Reverse Proxy< / a > ·
< / div >
< br / >
## Tech stack
< div align = "center" >









< / div >
2026-03-19 06:58:08 +08:00
2026-04-20 22:25:38 +08:00
Real-time sync via WebSocket (`ws`). State with Zustand. Auth via JWT + OAuth 2.1 + OIDC + TOTP MFA. Weather via Open-Meteo (no key required). Maps with Leaflet and Mapbox GL.
v2.5.2 — PWA, new branding, bug fixes
Progressive Web App:
- Service worker with Workbox caching (map tiles, API, uploads, CDN)
- Web app manifest with standalone display mode
- Custom app icon with PNG generation from SVG
- Apple meta tags, dynamic theme-color for dark/light mode
- iOS safe area handling
New Branding:
- Custom NOMAD logo (icon + text variants for light/dark mode)
- Logo used in navbar, login page, demo banner, admin, PDF export
- MuseoModerno font for login tagline
- Plane takeoff animation on login
- Liquid glass hover effect on dashboard spotlight & widgets
- Brand images protected from save/copy/drag
- "made with NOMAD" footer on PDF exports
Bug Fixes:
- Fix mobile note reorder (missing tripId prop)
- Fix Atlas city counting (strip postal codes, normalize case)
- Fix Atlas country detection (add Japanese/Korean/Thai names)
- Fix PDF note positioning (use order_index instead of sort_order)
- Fix PDF note icons (render actual icon instead of hardcoded notepad)
- Fix file source badge overflow on mobile (text truncation)
- Fix navbar dropdown z-index overlap with mobile plan/places buttons
- Fix dashboard trip card hover contrast in dark mode
- Fix day header hover color matching place background in dark mode
- Shorten settings button labels on mobile
UI Improvements:
- Mobile navbar shows icon only, desktop shows full logo
- NOMAD version badge in profile dropdown
- Top padding before first item in day planner
- Improved drag & drop stability (larger drop zones, less flickering)
2026-03-22 09:50:13 +08:00
2026-04-20 22:25:38 +08:00
< br / >
v2.5.2 — PWA, new branding, bug fixes
Progressive Web App:
- Service worker with Workbox caching (map tiles, API, uploads, CDN)
- Web app manifest with standalone display mode
- Custom app icon with PNG generation from SVG
- Apple meta tags, dynamic theme-color for dark/light mode
- iOS safe area handling
New Branding:
- Custom NOMAD logo (icon + text variants for light/dark mode)
- Logo used in navbar, login page, demo banner, admin, PDF export
- MuseoModerno font for login tagline
- Plane takeoff animation on login
- Liquid glass hover effect on dashboard spotlight & widgets
- Brand images protected from save/copy/drag
- "made with NOMAD" footer on PDF exports
Bug Fixes:
- Fix mobile note reorder (missing tripId prop)
- Fix Atlas city counting (strip postal codes, normalize case)
- Fix Atlas country detection (add Japanese/Korean/Thai names)
- Fix PDF note positioning (use order_index instead of sort_order)
- Fix PDF note icons (render actual icon instead of hardcoded notepad)
- Fix file source badge overflow on mobile (text truncation)
- Fix navbar dropdown z-index overlap with mobile plan/places buttons
- Fix dashboard trip card hover contrast in dark mode
- Fix day header hover color matching place background in dark mode
- Shorten settings button labels on mobile
UI Improvements:
- Mobile navbar shows icon only, desktop shows full logo
- NOMAD version badge in profile dropdown
- Top padding before first item in day planner
- Improved drag & drop stability (larger drop zones, less flickering)
2026-03-22 09:50:13 +08:00
2026-04-20 22:25:38 +08:00
< h2 id = "docker-compose-production" > Docker Compose (production)< / h2 >
v2.5.2 — PWA, new branding, bug fixes
Progressive Web App:
- Service worker with Workbox caching (map tiles, API, uploads, CDN)
- Web app manifest with standalone display mode
- Custom app icon with PNG generation from SVG
- Apple meta tags, dynamic theme-color for dark/light mode
- iOS safe area handling
New Branding:
- Custom NOMAD logo (icon + text variants for light/dark mode)
- Logo used in navbar, login page, demo banner, admin, PDF export
- MuseoModerno font for login tagline
- Plane takeoff animation on login
- Liquid glass hover effect on dashboard spotlight & widgets
- Brand images protected from save/copy/drag
- "made with NOMAD" footer on PDF exports
Bug Fixes:
- Fix mobile note reorder (missing tripId prop)
- Fix Atlas city counting (strip postal codes, normalize case)
- Fix Atlas country detection (add Japanese/Korean/Thai names)
- Fix PDF note positioning (use order_index instead of sort_order)
- Fix PDF note icons (render actual icon instead of hardcoded notepad)
- Fix file source badge overflow on mobile (text truncation)
- Fix navbar dropdown z-index overlap with mobile plan/places buttons
- Fix dashboard trip card hover contrast in dark mode
- Fix day header hover color matching place background in dark mode
- Shorten settings button labels on mobile
UI Improvements:
- Mobile navbar shows icon only, desktop shows full logo
- NOMAD version badge in profile dropdown
- Top padding before first item in day planner
- Improved drag & drop stability (larger drop zones, less flickering)
2026-03-22 09:50:13 +08:00
2026-03-19 07:21:57 +08:00
< details >
2026-04-20 22:25:38 +08:00
< summary > Full compose example with secure defaults< / summary >
2026-03-19 06:58:08 +08:00
2026-03-19 07:18:39 +08:00
```yaml
services:
app:
2026-03-29 04:41:03 +08:00
image: mauriceboe/trek:latest
2026-03-28 23:41:06 +08:00
container_name: trek
2026-03-31 21:59:11 +08:00
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- CHOWN
- SETUID
- SETGID
tmpfs:
- /tmp:noexec,nosuid,size=64m
2026-03-19 07:18:39 +08:00
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
2026-04-20 22:25:38 +08:00
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-} # generate with: openssl rand -hex 32
- TZ=${TZ:-UTC}
- LOG_LEVEL=${LOG_LEVEL:-info}
- ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-}
- APP_URL=${APP_URL:-} # required for OIDC + email links
# - FORCE_HTTPS=true # behind a TLS-terminating proxy
# - TRUST_PROXY=1
# - OIDC_ISSUER=https://auth.example.com
# - OIDC_CLIENT_ID=trek
# - OIDC_CLIENT_SECRET=supersecret
# - OIDC_DISPLAY_NAME=SSO
# - OIDC_ADMIN_CLAIM=groups
# - OIDC_ADMIN_VALUE=app-trek-admins
2026-03-19 07:18:39 +08:00
volumes:
2026-03-24 17:02:03 +08:00
- ./data:/app/data
- ./uploads:/app/uploads
2026-03-19 07:18:39 +08:00
restart: unless-stopped
2026-03-31 21:59:11 +08:00
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
2026-03-19 06:58:08 +08:00
```
2026-04-20 22:25:38 +08:00
Then:
2026-04-09 11:49:53 +08:00
2026-03-19 06:58:08 +08:00
```bash
2026-03-19 07:18:39 +08:00
docker compose up -d
2026-03-19 06:58:08 +08:00
```
2026-04-20 22:25:38 +08:00
**HTTPS notes:** `FORCE_HTTPS=true` is optional — it adds a 301 redirect, HSTS, CSP upgrade-insecure-requests, and forces the `secure` cookie flag. Only use it behind a TLS-terminating reverse proxy. `TRUST_PROXY=1` tells Express how many proxies sit in front so real client IPs and `X-Forwarded-Proto` work.
2026-03-19 07:21:57 +08:00
< / details >
2026-03-19 06:58:08 +08:00
2026-04-20 22:25:38 +08:00
< br / >
< h2 id = "helm-kubernetes" > Helm (Kubernetes)< / h2 >
```bash
helm repo add trek https://mauriceboe.github.io/TREK
helm repo update
helm install trek trek/trek
```
See [`charts/README.md` ](https://github.com/mauriceboe/TREK/blob/main/charts/README.md ) for values.
< h2 id = "install-as-app-pwa" > Install as App (PWA)< / h2 >
2026-03-19 07:02:18 +08:00
2026-04-20 22:25:38 +08:00
TREK works as a Progressive Web App — no App Store needed.
1. Open TREK in the browser (HTTPS required)
2. **iOS** : Share ▸ *Add to Home Screen*
3. **Android** : Menu ▸ *Install app* (or *Add to Home Screen* )
TREK then launches fullscreen with its own icon, just like a native app.
< br / >
## Updating
**Docker Compose:**
2026-03-25 23:47:10 +08:00
```bash
docker compose pull & & docker compose up -d
```
2026-04-20 22:25:38 +08:00
**Docker run** — reuse the original volume paths:
2026-03-25 23:47:10 +08:00
2026-03-19 07:02:18 +08:00
```bash
2026-03-29 04:41:03 +08:00
docker pull mauriceboe/trek
2026-03-28 23:41:06 +08:00
docker rm -f trek
2026-03-29 04:41:03 +08:00
docker run -d --name trek -p 3000:3000 -v ./data:/app/data -v ./uploads:/app/uploads --restart unless-stopped mauriceboe/trek
2026-03-19 06:58:08 +08:00
```
2026-04-20 22:25:38 +08:00
> Not sure which paths you used? `docker inspect trek --format '{{json .Mounts}}'` before removing the container.
2026-03-19 07:33:33 +08:00
2026-04-20 22:25:38 +08:00
Your data stays in the mounted `data` and `uploads` volumes — updates never touch it.
2026-03-19 06:58:08 +08:00
2026-04-20 22:25:38 +08:00
< h3 > Rotating the Encryption Key< / h3 >
2026-04-01 15:35:32 +08:00
2026-04-20 22:25:38 +08:00
If you need to rotate `ENCRYPTION_KEY` (e.g. upgrading from a version that derived encryption from `JWT_SECRET` ):
2026-04-01 15:35:32 +08:00
```bash
docker exec -it trek node --import tsx scripts/migrate-encryption.ts
```
2026-04-20 22:25:38 +08:00
The script creates a timestamped DB backup before making changes and prompts for old + new keys (input is not echoed).
2026-04-01 15:35:32 +08:00
2026-04-20 22:25:38 +08:00
< h2 id = "reverse-proxy" > Reverse Proxy< / h2 >
2026-03-19 06:58:08 +08:00
2026-04-20 22:25:38 +08:00
For production, put TREK behind a TLS-terminating reverse proxy. TREK uses WebSockets for real-time sync, so the proxy **must** support WebSocket upgrades on `/ws` .
2026-03-19 23:01:05 +08:00
< details >
< summary > Nginx< / summary >
```nginx
server {
listen 80;
2026-03-29 23:51:03 +08:00
server_name trek.yourdomain.com;
2026-03-19 23:01:05 +08:00
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
2026-03-29 23:51:03 +08:00
server_name trek.yourdomain.com;
2026-03-19 23:01:05 +08:00
2026-04-20 22:25:38 +08:00
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
2026-03-19 23:01:05 +08:00
2026-04-20 22:25:38 +08:00
client_max_body_size 50m;
location / {
2026-03-19 23:01:05 +08:00
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
2026-04-20 22:25:38 +08:00
location /ws {
2026-03-19 23:01:05 +08:00
proxy_pass http://localhost:3000;
2026-04-20 22:25:38 +08:00
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
2026-03-19 23:01:05 +08:00
proxy_set_header Host $host;
}
}
```
< / details >
< details >
< summary > Caddy< / summary >
2026-04-20 22:25:38 +08:00
```caddy
2026-03-29 23:51:03 +08:00
trek.yourdomain.com {
2026-03-19 07:02:18 +08:00
reverse_proxy localhost:3000
}
2026-03-19 06:58:08 +08:00
```
2026-04-20 22:25:38 +08:00
Caddy handles TLS and WebSockets automatically.
2026-03-19 23:01:05 +08:00
< / details >
2026-04-20 22:25:38 +08:00
< br / >
## Environment variables
< details >
< summary > < b > Full reference< / b > < / summary >
< br / >
2026-03-29 23:51:03 +08:00
| Variable | Description | Default |
|----------|-------------|---------|
2026-03-31 21:45:20 +08:00
| **Core** | | |
2026-03-29 23:51:03 +08:00
| `PORT` | Server port | `3000` |
2026-03-31 21:45:20 +08:00
| `NODE_ENV` | Environment (`production` / `development` ) | `production` |
2026-04-01 15:47:31 +08:00
| `ENCRYPTION_KEY` | At-rest encryption key for stored secrets (API keys, MFA, SMTP, OIDC). Recommended: generate with `openssl rand -hex 32` . If unset, falls back to `data/.jwt_secret` (existing installs) or auto-generates a key (fresh installs). | Auto |
2026-03-31 21:45:20 +08:00
| `TZ` | Timezone for logs, reminders and cron jobs (e.g. `Europe/Berlin` ) | `UTC` |
| `LOG_LEVEL` | `info` = concise user actions, `debug` = verbose details | `info` |
2026-04-20 22:25:38 +08:00
| `DEFAULT_LANGUAGE` | Default language on the login page for users with no saved preference. Browser/OS language is auto-detected first; this is the fallback. Supported: `de` , `en` , `es` , `fr` , `hu` , `nl` , `br` , `cs` , `pl` , `ru` , `zh` , `zh-TW` , `it` , `ar` | `en` |
2026-03-31 21:45:20 +08:00
| `ALLOWED_ORIGINS` | Comma-separated origins for CORS and email links | same-origin |
2026-04-20 22:25:38 +08:00
| `FORCE_HTTPS` | Optional. When `true` : 301-redirects HTTP to HTTPS, sends HSTS, adds CSP `upgrade-insecure-requests` , forces the session cookie `secure` flag. Useful behind a TLS-terminating reverse proxy. Requires `TRUST_PROXY` . | `false` |
| `COOKIE_SECURE` | Controls the `secure` flag on the `trek_session` cookie. Auto-derived: on when `NODE_ENV=production` or `FORCE_HTTPS=true` . Escape hatch: set `false` to allow session cookies over plain HTTP. Not recommended in production. | auto |
| `TRUST_PROXY` | Number of trusted reverse proxies. Tells Express to read client IP from `X-Forwarded-For` and protocol from `X-Forwarded-Proto` . Defaults to `1` in production; off in dev unless set. | `1` |
| `ALLOW_INTERNAL_NETWORK` | Allow outbound requests to private/RFC-1918 IPs (e.g. Immich on your LAN). Loopback and link-local addresses remain blocked. | `false` |
| `APP_URL` | Public base URL of this instance (e.g. `https://trek.example.com` ). Required when OIDC is enabled; used as base for email notification links. | — |
2026-03-31 21:45:20 +08:00
| **OIDC / SSO** | | |
| `OIDC_ISSUER` | OpenID Connect provider URL | — |
2026-03-29 23:51:03 +08:00
| `OIDC_CLIENT_ID` | OIDC client ID | — |
| `OIDC_CLIENT_SECRET` | OIDC client secret | — |
2026-03-31 21:45:20 +08:00
| `OIDC_DISPLAY_NAME` | Label shown on the SSO login button | `SSO` |
2026-04-20 22:25:38 +08:00
| `OIDC_ONLY` | Force SSO-only mode: disables password login + registration, regardless of Admin > Settings. The first SSO login becomes admin. | `false` |
2026-04-02 13:46:27 +08:00
| `OIDC_ADMIN_CLAIM` | OIDC claim used to identify admin users | — |
| `OIDC_ADMIN_VALUE` | Value of the OIDC claim that grants admin role | — |
2026-04-20 22:25:38 +08:00
| `OIDC_SCOPE` | Space-separated OIDC scopes. **Fully replaces** the default — always include `openid email profile` . | `openid email profile` |
| `OIDC_DISCOVERY_URL` | Override the auto-constructed OIDC discovery endpoint (e.g. Authentik: `.../application/o/trek/.well-known/openid-configuration` ) | — |
| **Initial setup** | | |
| `ADMIN_EMAIL` | Email for the first admin on initial boot. Must be set together with `ADMIN_PASSWORD` . If either is omitted a random password is printed to the server log. No effect once a user exists. | `admin@trek.local` |
| `ADMIN_PASSWORD` | Password for the first admin on initial boot. Pairs with `ADMIN_EMAIL` . | random |
2026-03-31 21:45:20 +08:00
| **Other** | | |
| `DEMO_MODE` | Enable demo mode (hourly data resets) | `false` |
2026-04-11 08:28:54 +08:00
| `MCP_RATE_LIMIT` | Max MCP API requests per user per minute | `300` |
| `MCP_MAX_SESSION_PER_USER` | Max concurrent MCP sessions per user | `20` |
2026-03-29 23:51:03 +08:00
2026-04-20 22:25:38 +08:00
< / details >
2026-03-19 07:18:39 +08:00
2026-04-20 22:25:38 +08:00
< br / >
2026-03-19 07:18:39 +08:00
2026-03-19 07:02:18 +08:00
## Data & Backups
2026-03-19 06:58:08 +08:00
2026-04-20 22:25:38 +08:00
- **Database** — SQLite, stored in `./data/travel.db`
- **Uploads** — stored in `./uploads/`
- **Logs** — `./data/logs/trek.log` (auto-rotated)
- **Backups** — create and restore via Admin Panel
- **Auto-Backups** — configurable schedule and retention in Admin Panel
< br / >
2026-03-19 06:58:08 +08:00
2026-03-19 07:02:18 +08:00
## License
2026-03-19 06:58:08 +08:00
2026-04-20 22:25:38 +08:00
TREK is [AGPL v3 ](LICENSE ). Self-host freely for personal or internal company use. If you modify and offer TREK as a network service to third parties, your modifications must be open-sourced under the same licence.