6.8 KiB
Install: Helm
Deploy TREK on Kubernetes using the official Helm chart.
Add the Chart Repository
helm repo add trek https://mauriceboe.github.io/TREK
helm repo update
Basic Install
helm install trek trek/trek
This deploys TREK with default values: a ClusterIP service on port 3000, 1 Gi PVCs for data and uploads, and no ingress.
Encryption Key
ENCRYPTION_KEY encrypts stored secrets (API keys, MFA, SMTP, OIDC) at rest. There are three ways to handle it:
Option 1 — Let the chart generate a random key (recommended for new installs):
helm install trek trek/trek --set generateEncryptionKey=true
The chart generates a 32-character alphanumeric key at install time and preserves it across upgrades. Note that this differs from the 64-character hex key produced by openssl rand -hex 32 — both formats are accepted by the server.
Option 2 — Set an explicit key:
helm install trek trek/trek \
--set secretEnv.ENCRYPTION_KEY=$(openssl rand -hex 32)
Option 3 — Use an existing Kubernetes Secret:
kubectl create secret generic trek-secrets \
--from-literal=ENCRYPTION_KEY=$(openssl rand -hex 32)
helm install trek trek/trek \
--set existingSecret=trek-secrets
If existingSecret uses a different key name than ENCRYPTION_KEY, specify it with --set existingSecretKey=MY_KEY_NAME.
Note: If both
generateEncryptionKeyandexistingSecretare set,existingSecrettakes precedence. Only one method should be active at a time.
Note: If
ENCRYPTION_KEYis left empty, the server resolves it automatically: existing installs fall back todata/.jwt_secret(encrypted data stays readable after upgrade); fresh installs auto-generate a key persisted to the data PVC.
Note:
JWT_SECRETis managed entirely by the server — auto-generated on first start and persisted to the data PVC. It can be rotated via the admin panel (Settings → Danger Zone → Rotate JWT Secret). No Helm configuration is needed or supported for it.
Admin Account
ADMIN_EMAIL and ADMIN_PASSWORD are set via secretEnv. They are only used on first boot when no users exist yet. Both must be set together — if either is missing, the server ignores both values and instead creates the admin account with email admin@trek.local and a random password, which is printed to the server log.
helm install trek trek/trek \
--set secretEnv.ADMIN_EMAIL=admin@example.com \
--set secretEnv.ADMIN_PASSWORD=<your-secure-password>
Note: When
OIDC_ONLY=trueis configured together withOIDC_ISSUERandOIDC_CLIENT_ID, no local admin account is created on first boot. Instead, the first user to log in via SSO automatically becomes admin.
Key values.yaml Settings
Image
image:
repository: mauriceboe/trek
# tag: latest # defaults to the chart's appVersion
pullPolicy: IfNotPresent
# Optional: pull secrets for private registries
imagePullSecrets: []
# - name: my-registry-secret
Service
service:
type: ClusterIP # change to LoadBalancer or NodePort to expose externally
port: 3000
Plain Environment Variables (env)
env:
NODE_ENV: production
PORT: 3000
# TZ: "Europe/Berlin" # timezone for logs, reminders, cron jobs
# LOG_LEVEL: "info" # "info" = concise, "debug" = verbose
# DEFAULT_LANGUAGE: "en" # fallback language on login page; supported: de, en, es, fr, hu, nl, br, cs, pl, ru, zh, zh-TW, it, ar
# ALLOWED_ORIGINS: "https://trek.example.com"
# APP_URL: "https://trek.example.com"
# FORCE_HTTPS: "false" # enable HTTPS redirect + HSTS; requires TRUST_PROXY
# TRUST_PROXY: "1" # proxy hops for X-Forwarded-For/Proto; defaults to 1 in production
# COOKIE_SECURE: "true" # auto-derived; set "false" only for local HTTP testing
# ALLOW_INTERNAL_NETWORK: "false" # set "true" if Immich or other services are on a private network
# DEMO_MODE: "false" # enable demo mode (hourly data resets)
# MCP_RATE_LIMIT: "300" # max MCP requests per user per minute
# OIDC_ISSUER: "https://auth.example.com"
# OIDC_CLIENT_ID: "trek"
# OIDC_DISPLAY_NAME: "SSO"
# OIDC_ONLY: "false" # force SSO-only mode; disables password login
# OIDC_ADMIN_CLAIM: "" # OIDC claim used to identify admin users
# OIDC_ADMIN_VALUE: "" # value of that claim that grants admin role
# OIDC_SCOPE: "openid email profile groups"
# OIDC_DISCOVERY_URL: "" # override for providers with non-standard discovery paths (e.g. Authentik)
Sensitive Variables (secretEnv)
These are stored in a Kubernetes Secret and injected as environment variables:
secretEnv:
ENCRYPTION_KEY: "" # recommended: openssl rand -hex 32
ADMIN_EMAIL: "" # initial admin email (first boot only)
ADMIN_PASSWORD: "" # initial admin password (first boot only)
OIDC_CLIENT_SECRET: "" # set if using OIDC
Alternatively, use generateEncryptionKey: true to let the chart generate and manage the encryption key, or point existingSecret / existingSecretKey at an existing Kubernetes Secret.
Persistent Storage
persistence:
enabled: true
data:
size: 1Gi # SQLite database, logs, secrets
uploads:
size: 1Gi # uploaded files — increase if you expect large media uploads
Resource Limits
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
Ingress
ingress:
enabled: true
className: "nginx" # your ingress class
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "86400" # required for WebSockets
nginx.ingress.kubernetes.io/proxy-body-size: "500m" # required for backup restore
hosts:
- host: trek.example.com
paths:
- /
tls:
- secretName: trek-tls
hosts:
- trek.example.com
Important: TREK uses WebSockets on
/ws. Your ingress controller must support WebSocket upgrades. Setproxy-read-timeoutto at least86400andproxy-body-sizeto at least500mfor backup restores.
Note: Keep
env.ALLOWED_ORIGINSin sync withingress.hosts— the chart does not synchronize these automatically.
Note: When using ingress with TLS termination, set
env.FORCE_HTTPS: "true"andenv.TRUST_PROXY: "1"to enable HTTPS redirects, HSTS, and secure cookies.
Upgrade
helm repo update
helm upgrade trek trek/trek
Full Values Reference
See the charts/README.md for all available values.
Next Steps
- Environment-Variables — full variable reference
- Reverse-Proxy — proxy configuration for non-Kubernetes deployments