2026-03-19 06:58:08 +08:00
services :
app :
2026-03-29 03:23:13 +08:00
image : mauriceboe/trek:latest
2026-03-28 23:41:06 +08:00
container_name : trek
feat: notifications, audit logging, and admin improvements
- Add centralized notification service with webhook (Discord/Slack) and
email (SMTP) support, triggered for trip invites, booking changes,
collab messages, and trip reminders
- Webhook sends one message per event (group channel); email sends
individually per trip member, excluding the actor
- Discord invite notifications now include the invited user's name
- Add LOG_LEVEL env var (info/debug) controlling console and file output
- INFO logs show user email, action, and IP for audit events; errors
for HTTP requests
- DEBUG logs show every request with full body/query (passwords redacted),
audit details, notification params, and webhook payloads
- Add persistent trek.log file logging with 10MB rotation (5 files)
in /app/data/logs/
- Color-coded log levels in Docker console output
- Timestamps without timezone name (user sets TZ via Docker)
- Add Test Webhook and Save buttons to admin notification settings
- Move notification event toggles to admin panel
- Add daily trip reminder scheduler (9 AM, timezone-aware)
- Wire up booking create/update/delete and collab message notifications
- Add i18n keys for notification UI across all 13 languages
Made-with: Cursor
2026-03-31 20:01:33 +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 06:58:08 +08:00
ports :
- "3000:3000"
environment :
- NODE_ENV=production
- PORT=3000
2026-04-01 15:48:14 +08:00
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-} # Recommended. Generate with: openssl rand -hex 32. If unset, falls back to data/.jwt_secret (existing installs) or auto-generates a key (fresh installs).
2026-03-31 21:59:11 +08:00
- TZ=${TZ:-UTC} # Timezone for logs, reminders and scheduled tasks (e.g. Europe/Berlin)
- LOG_LEVEL=${LOG_LEVEL:-info} # info = concise user actions; debug = verbose admin-level details
2026-04-15 09:10:57 +08:00
# - DEFAULT_LANGUAGE=en # 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
2026-03-31 21:59:11 +08:00
- ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-} # Comma-separated origins for CORS and email notification links
2026-04-11 21:25:41 +08:00
# - FORCE_HTTPS=true # Optional. Enables HTTPS redirect, HSTS, CSP upgrade-insecure-requests, and secure cookies behind a TLS proxy
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.
2026-04-24 01:49:36 +08:00
# - HSTS_INCLUDE_SUBDOMAINS=false # When true: adds includeSubDomains to the HSTS header. Only effective when HSTS is active. Leave false if sibling subdomains still run over plain HTTP.
2026-04-11 21:25:41 +08:00
# - COOKIE_SECURE=false # Escape hatch: force session cookies over plain HTTP even in production. Not recommended.
# - TRUST_PROXY=1 # Trusted proxy count for X-Forwarded-For / X-Forwarded-Proto. Required for FORCE_HTTPS to work.
# - ALLOW_INTERNAL_NETWORK=false # Set to true if Immich or other services are hosted on your local network (RFC-1918 IPs). Loopback and link-local addresses remain blocked regardless.
2026-04-03 09:51:29 +08:00
# - APP_URL=https://trek.example.com # Public base URL — required when OIDC is enabled (must match the redirect URI registered with your IdP); also used as base URL for links in email notifications
2026-04-02 03:44:02 +08:00
# - OIDC_ISSUER=https://auth.example.com # OpenID Connect provider URL
# - OIDC_CLIENT_ID=trek # OpenID Connect client ID
# - OIDC_CLIENT_SECRET=supersecret # OpenID Connect client secret
# - OIDC_DISPLAY_NAME=SSO # Label shown on the SSO login button
2026-04-12 02:21:22 +08:00
# - OIDC_ONLY=false # Set true to force SSO-only mode: disables password login and registration, overrides Admin > Settings toggles, cannot be changed at runtime
2026-04-02 13:46:27 +08:00
# - OIDC_ADMIN_CLAIM=groups # OIDC claim used to identify admin users
# - OIDC_ADMIN_VALUE=app-trek-admins # Value of the OIDC claim that grants admin role
2026-04-04 20:47:23 +08:00
# - OIDC_SCOPE=openid email profile # Fully overrides the default. Add extra scopes as needed (e.g. add groups if using OIDC_ADMIN_CLAIM)
2026-04-02 03:44:02 +08:00
# - OIDC_DISCOVERY_URL= # Override the OIDC discovery endpoint for providers with non-standard paths (e.g. Authentik)
2026-04-02 05:09:57 +08:00
# - ADMIN_EMAIL=admin@trek.local # Initial admin e-mail — only used on first boot when no users exist
# - ADMIN_PASSWORD=changeme # Initial admin password — only used on first boot when no users exist
2026-04-11 08:28:54 +08:00
# - MCP_RATE_LIMIT=300 # Max MCP API requests per user per minute (default: 300)
# - MCP_MAX_SESSION_PER_USER=20 # Max concurrent MCP sessions per user (default: 20)
2026-03-19 06:58:08 +08:00
volumes :
- ./data:/app/data
- ./uploads:/app/uploads
restart : unless-stopped
healthcheck :
2026-03-25 07:14:53 +08:00
test : [ "CMD" , "wget" , "-qO-" , "http://localhost:3000/api/health" ]
2026-03-19 06:58:08 +08:00
interval : 30s
timeout : 10s
retries : 3
start_period : 15s