Adds the complete TREK documentation wiki covering installation, trip planning, admin panel, MCP/AI integration, addons, and operations. Also fixes encrypt-at-rest gaps: mapbox_access_token, Synology credentials, per-user webhook/ntfy tokens, and photo passphrases are now rotated by migrate-encryption.ts and stored encrypted via settingsService.
4.7 KiB
Reverse Proxy
Putting TREK behind a TLS-terminating reverse proxy is strongly recommended for production.
Why HTTPS Matters for TREK
- PWA install requires HTTPS — browsers block "Add to Home Screen" on plain HTTP.
- Session cookies — the
trek_sessioncookie is markedsecurein production, so it won't be sent over HTTP. - OIDC / SSO — identity providers require the redirect URI to use HTTPS.
- MCP — the MCP API requires HTTPS for OAuth 2.1 auth.
Two Hard Requirements
Whatever proxy you use, it must satisfy two constraints:
- WebSocket upgrades on
/ws— TREK uses WebSockets for real-time sync. Setproxy_read_timeout 86400(Nginx) or rely on Caddy's automatic upgrade handling. - Body size ≥ 500 MB — backup restore ZIPs can include the full uploads directory. Set
client_max_body_size 500m(Nginx) orrequest_body_max_size 500mb(Caddy) if you restore large backups.
Nginx
server {
listen 80;
server_name trek.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name trek.yourdomain.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_read_timeout 86400;
# File uploads are capped at 50 MB; backup restore ZIPs can include the full
# uploads directory and may exceed that — raise this value if restores fail.
client_max_body_size 500m;
}
location / {
proxy_pass http://localhost:3000;
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;
# Needed for backup restore uploads — can exceed the Nginx default of 1 MB.
client_max_body_size 500m;
}
}
Key lines:
proxy_read_timeout 86400— keeps WebSocket connections alive (86400 s = 24 h).client_max_body_size 500m— allows large backup restore uploads; set in both locations.X-Forwarded-Proto $scheme— tells TREK whether the original request was HTTPS; required forFORCE_HTTPSredirect and cookie security to work correctly.
Caddy
Caddy handles WebSocket upgrades automatically:
trek.yourdomain.com {
reverse_proxy localhost:3000
}
For large backup restores, add:
trek.yourdomain.com {
request_body max_size 500mb
reverse_proxy localhost:3000
}
HTTPS Environment Variables
Four variables control how TREK behaves behind a proxy. They work as a group:
| Variable | Purpose | Default |
|---|---|---|
FORCE_HTTPS |
When true: 301-redirects HTTP→HTTPS (except /api/health), sends HSTS (max-age=31536000), adds CSP upgrade-insecure-requests, forces cookie secure flag |
false |
TRUST_PROXY |
Number of trusted proxy hops. Lets Express read the real client IP from X-Forwarded-For. Automatically set to 1 in production even if not explicitly configured. |
1 (production), off (development) |
COOKIE_SECURE |
Controls the secure flag on trek_session. Auto-derived as true when NODE_ENV=production or FORCE_HTTPS=true. Set to false explicitly to allow cookies over plain HTTP (e.g. LAN testing without TLS). |
auto |
ALLOWED_ORIGINS |
Comma-separated list of allowed CORS origins (e.g. https://trek.example.com). In production without this set, all cross-origin requests are blocked. In development without this set, all origins are allowed. |
blocked in prod, open in dev |
Note on
FORCE_HTTPSand proxy headers: The HTTPS redirect readsX-Forwarded-Protodirectly from the incoming headers — it does not depend on Express'strust proxysetting. If you setFORCE_HTTPS=trueand your reverse proxy correctly sendsX-Forwarded-Proto: https, the redirect will work regardless ofTRUST_PROXY. However, you still needTRUST_PROXYset so Express resolves the correct client IP fromX-Forwarded-For.
If you access TREK directly on http://<host>:3000 without a proxy, leave FORCE_HTTPS unset and do not set TRUST_PROXY.
See [Environment-Variables] for full documentation of these and all other variables.
Next Steps
- [Environment-Variables] — full variable reference including OIDC
- [Install-Docker-Compose] — production compose file with proxy-ready env vars