TREK 5.0 mit Docker Compose: Reiseplaner installieren, sichern und updaten
TREK ist ein selbst gehosteter Reiseplaner mit Karten, Tagesplänen und gemeinsamer Planung. Diese Anleitung zeigt Installation von TREK 5.0.0 mit Docker Compose, HTTPS, eingebautes Backup, Restore nach Totalverlust, die Rolle des ENCRYPTION_KEY und das getestete Update von 4.3.4 auf 5.0.0.
Geprüft am 26.10.2026 · für TREK 5.0.0
Mit KI erstellt – redaktionelle Prüfung ausstehend
WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

TREK ist ein selbst gehosteter Reiseplaner: Reisen mit Tagesplänen, Orten auf der Karte, Buchungen, Packlisten, Kosten und gemeinsamer Planung im Team oder in der Familie. Das Projekt steht unter AGPL-3.0 und hat auf GitHub rund 15.000 Sterne; das Release 5.0.0 vom 25. Oktober 2026 gehört zu den meistdiskutierten Selfhosting-Themen der Woche. Version 5.0 bringt das Tours-Addon für Wanderungen, Radtouren und Skitouren, ein Fotobuch-Studio, einen Assistenten und eine MCP-Schnittstelle. Wichtiger für Admins: Die Datenbankschicht wurde umgebaut, und TREK legt vor jeder Migration selbst eine Kopie der Datenbank an. Diese Anleitung zeigt die Installation mit Docker Compose, die Einrichtung, Backup und Wiederherstellung sowie das Update von 4.3.4 auf 5.0.0, so wie wir es im Labor durchgespielt haben.
Voraussetzungen
TREK ist sparsam. Für eine Familie oder ein kleines Team reicht ein Linux-Server oder Mini-PC mit 2 CPU-Kernen, 2 bis 4 GB RAM und 10 GB freiem Speicher; x86_64 und ARM64 werden als Image angeboten. Planen Sie zusätzlich Platz für die Datenbankkopie beim Update und für die Backup-ZIPs ein, die TREK unter data/backups ablegt.
- Docker Engine mit Docker Compose Plugin, eingerichtet wie in unserer Grundlage für Docker Compose unter Linux beschrieben.
- Eine Domain oder Subdomain, zum Beispiel
trek.example.de, und ein Reverse Proxy mit TLS, etwa Caddy mit automatischem HTTPS. - Ausgehender Internetzugang für Kartenkacheln und Ortssuche. Die Ortssuche fragt ab 4.3.0 standardmäßig die TREK Places API unter
places.liketrek.com; wer das nicht möchte, setztTREK_PLACES_ENABLED=false. - Ein Ziel für Backups außerhalb des Servers, etwa ein NAS oder ein Restic-Repository.
| Eckdatum | Wert |
|---|---|
| Image | mauriceboe/trek:5.0.0 (Docker Hub, auch 5.0, 5, latest) |
| Port | 3000/tcp (Weboberfläche und API) |
| Volumes | ./data:/app/data (Datenbank travel.db, Schlüssel, Backups), ./uploads:/app/uploads |
| Wichtige Env | ENCRYPTION_KEY, TZ, ALLOWED_ORIGINS, ADMIN_EMAIL/ADMIN_PASSWORD (nur Erststart) |
| Healthcheck | /api/health liefert {"status":"ok"} |
| Lizenz | AGPL-3.0 |
Schritt 1: Projektordner und .env anlegen
Legen Sie einen Ordner an und erzeugen Sie den Verschlüsselungsschlüssel. TREK verschlüsselt mit ihm gespeicherte Geheimnisse wie API-Schlüssel, SMTP-Passwort, OIDC-Secret und die TOTP-Geheimnisse der Zwei-Faktor-Anmeldung. Reisen, Orte und Benutzer liegen unverschlüsselt in der SQLite-Datenbank.
mkdir -p /opt/trek && cd /opt/trek
cat > .env <<EOF
ENCRYPTION_KEY=$(openssl rand -hex 32)
TZ=Europe/Berlin
LOG_LEVEL=info
ALLOWED_ORIGINS=https://trek.example.de
ADMIN_EMAIL=admin@example.de
ADMIN_PASSWORD=$(openssl rand -base64 18)
EOF
chmod 600 .env
grep ADMIN_PASSWORD .env
ALLOWED_ORIGINS ist die öffentliche Adresse; TREK leitet daraus auch die Basis-URL für Links in Benachrichtigungen ab. ADMIN_EMAIL und ADMIN_PASSWORD wirken nur beim allerersten Start, solange noch kein Benutzer existiert.
Verifizieren: ls -l .env zeigt -rw-------, und grep -c . .env meldet 6 Zeilen. Notieren Sie das Admin-Passwort im Passwortmanager.
Schritt 2: compose.yaml mit festem Versions-Tag
Die Datei folgt der offiziellen docker-compose.yml des Projekts mit zwei Änderungen: Das Image ist auf 5.0.0 festgeschrieben statt latest, und die Admin-Zugangsdaten kommen aus der .env. Im Original stehen sie als auskommentierte feste Werte, weil die Upstream-Datei kein env_file nutzt und nur Variablen mit ${…} aus der .env übernimmt.
services:
app:
image: mauriceboe/trek:5.0.0
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- CHOWN
- SETUID
- SETGID
tmpfs:
- /tmp:noexec,nosuid,size=128m
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-}
- TZ=${TZ:-UTC}
- LOG_LEVEL=${LOG_LEVEL:-info}
- ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-}
- ADMIN_EMAIL=${ADMIN_EMAIL:-}
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
volumes:
- ./data:/app/data
- ./uploads:/app/uploads
restart: unless-stopped
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:$${PORT:-3000}/api/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
Die Härtung ist bereits ab Werk dabei: read-only Dateisystem, alle Capabilities entfernt bis auf die drei, die das Startskript zum Wechsel auf den Benutzer node braucht, und ein Healthcheck. Was diese Optionen leisten, erklärt unsere Anleitung zu Secrets, Healthchecks und Non-Root-Containern. Das Startskript setzt die Besitzrechte von data und uploads bei jedem Start auf UID 1000; Sie müssen die Ordner nicht von Hand vorbereiten. Docker aus Snap verträgt no-new-privileges laut Projekt-Wiki nicht.
Verifizieren: docker compose config --quiet endet ohne Ausgabe, und docker compose config | grep image zeigt mauriceboe/trek:5.0.0.
Schritt 3: Starten und Admin-Konto prüfen
docker compose up -d
docker compose ps
docker compose logs --no-log-prefix | grep -A3 "First Run"
curl -s http://localhost:3000/api/health
Im Labor war TREK nach 10 bis 15 Sekunden bereit. Beim Erststart legt der Container das Admin-Konto an und meldet im Log einen Kasten mit First Run: Admin Account Created und der E-Mail-Adresse.
Die Version lesen Sie am Image-Label ab, nicht am Tag in der Datei:
docker inspect $(docker compose ps -q app) \
--format '{{index .Config.Labels "org.opencontainers.image.version"}}'
Ändern Sie danach das Admin-Passwort in der Oberfläche und entfernen Sie ADMIN_PASSWORD aus der .env.

Verifizieren: docker compose ps zeigt healthy, curl liefert {"status":"ok"}, das Label meldet 5.0.0.
Schritt 4: HTTPS davor schalten
Mit NODE_ENV=production setzt TREK das Session-Cookie trek_session immer mit dem Attribut Secure. Über reines HTTP nimmt der Server den Login zwar an, antwortet aber mit dem Hinweis "insecureCookie":true, und der Browser verwirft das Cookie. Im Test sah die Antwort so aus:
Set-Cookie: trek_session=…; Path=/; HttpOnly; Secure; SameSite=Lax
{"user":"admin@example.de","role":"admin","insecureCookie":true}
Betreiben Sie TREK deshalb hinter einem Reverse Proxy mit TLS. Ein minimaler Caddy-Block genügt:
trek.example.de {
reverse_proxy 127.0.0.1:3000
}
Laut Wiki aktivieren Sie hinter dem Proxy zusätzlich FORCE_HTTPS=true und TRUST_PROXY=1 (in der compose.yaml einkommentieren), damit Weiterleitungen und HSTS greifen. Läuft der Proxy auf demselben Host, binden Sie den Port mit "127.0.0.1:3000:3000" nur lokal.
Verifizieren: curl -sI https://trek.example.de/api/health liefert HTTP/2 200, und nach dem Login im Browser bleiben Sie beim Neuladen angemeldet.
Schritt 5: Erste Reise anlegen
Legen Sie unter Meine Reisen eine Reise mit Zeitraum an und fügen Sie einen Ort hinzu. Dasselbe geht per REST-API mit dem Token aus dem Login; so entstanden im Labor die Marker-Daten für den Restore-Test:
TOKEN=$(curl -s -H 'Content-Type: application/json' \
-d '{"email":"admin@example.de","password":"IHR-PASSWORT"}' \
https://trek.example.de/api/auth/login | jq -r .token)
curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"title":"Marker-Reise Dresden 2026","start_date":"2026-11-06","end_date":"2026-11-08"}' \
https://trek.example.de/api/trips
curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Marker-Ort Frauenkirche","lat":51.0519,"lng":13.7416}' \
https://trek.example.de/api/trips/1/places
Ein falsches Passwort beantwortet TREK mit HTTP 401 und {"error":"Invalid email or password"}; der Login ist zudem pro IP begrenzt.

Verifizieren: curl -s -H "Authorization: Bearer $TOKEN" https://trek.example.de/api/trips/1/places listet den Ort mit Koordinaten, und die Reise erscheint im Dashboard.
Schritt 6: Backup einrichten
TREK hat eine eingebaute Sicherung unter Admin, Backup. Backup erstellen schreibt ein ZIP nach data/backups; im Bereich Auto-Backup planen Sie stündliche bis monatliche Läufe mit Aufbewahrungsdauer. Das ZIP aus unserem Test enthielt die Datenbank als konsistenten Schnappschuss und die Uploads:
2383872 travel.db
70 uploads/avatars/7c15b302-….png
Eine Datei .encryption_key fehlt darin, und das ist so gewollt: Wenn Sie ENCRYPTION_KEY per Umgebungsvariable setzen, packt TREK den Schlüssel nicht ins Archiv. Die .env gehört deshalb getrennt und gut geschützt ins Backup. Ohne gesetzte Variable liegt der Schlüssel dagegen im ZIP, und das Archiv ist dann so sensibel wie der Schlüssel selbst.
Zusätzlich empfiehlt sich eine Dateisicherung bei gestopptem Container, denn eine laufende SQLite-Datenbank mit WAL-Dateien lässt sich nicht konsistent kopieren:
cd /opt/trek
docker compose stop
tar czf /backup/trek-$(date +%F).tgz data uploads .env compose.yaml
docker compose start

Verifizieren: unzip -l data/backups/backup-*.zip zeigt travel.db und die Uploads, tar tzf /backup/trek-*.tgz | head listet data/travel.db, data/.encryption_key und .env.
Schritt 7: Wiederherstellen nach Totalverlust
Wir haben im Labor den Container entfernt und data sowie uploads gelöscht. Der Neustart lieferte eine leere Instanz mit frisch angelegtem Admin aus der .env, die Reiseliste war leer. Danach gibt es zwei getestete Wege zurück.
Weg A, Backup-ZIP: In der leeren Instanz unter Admin, Backup auf Backup hochladen klicken und das ZIP wählen, oder per API:
curl -s -H "Authorization: Bearer $TOKEN" \
-F backup=@backup-2026-10-26T01-23-07.zip \
https://trek.example.de/api/backup/upload-restore
# {"success":true}
Reise, Ort und Avatar waren danach wieder da. Die ersetzte Datenbank legt TREK als data/pre-restore-<Zeit>.db ab, ein versehentlicher Restore lässt sich also von Hand rückgängig machen.
Weg B, Dateisicherung:
cd /opt/trek
docker compose down
rm -rf data uploads
tar xzf /backup/trek-2026-10-26.tgz data uploads
docker compose up -d
Verifizieren: Nach beiden Wegen meldet /api/health wieder ok, der Login mit dem alten Passwort gelingt und /api/trips/1/places liefert den Marker-Ort mit den ursprünglichen Koordinaten.
Schritt 8: Update von 4.3.x auf 5.0.0
Unser Labor startete mit mauriceboe/trek:4.3.4, legte Reise und Ort an und stellte dann den Tag in der compose.yaml auf 5.0.0 um. Vorher gehört ein Backup nach Schritt 6 dazu.
df -h /opt/trek/data
sed -i 's#mauriceboe/trek:4.3.4#mauriceboe/trek:5.0.0#' compose.yaml
docker compose pull && docker compose up -d
docker compose logs --no-log-prefix | grep -E 'Copy of the database|pending migration'
Das Log zeigt die neue Datenbankmigration und die automatische Kopie:
[DB] Copy of the database before migrating: /app/data/pre-migrate-legacy-244-20261026T012259Z.db
[DB] Applying 83 pending migration(s)
Nach 15 Sekunden war der Container wieder gesund, das Label meldete 5.0.0, Login und Marker-Daten waren unverändert. Die Kopie ist Ihr einziger Rückweg: Migrationen laufen nur vorwärts. Ein Image 4.3.x startet laut Release-Notes ohne Warnung auch auf einer migrierten Datenbank. Für ein Zurück stoppen Sie TREK, kopieren die pre-migrate-…db über data/travel.db, löschen travel.db-wal und travel.db-shm und starten das alte Image. Uploads enthält die Kopie nicht. Kann TREK die Kopie mangels Platz nicht schreiben, startet es laut Release-Notes nicht und nennt den Pfad. Benachrichtigungen über neue Versionen liefern Werkzeuge aus unserer Anleitung zu Container-Updates mit Diun und WUD.

Verifizieren: ls data/pre-migrate-* zeigt die Kopie, das Image-Label meldet 5.0.0, und Ihre Reisen sind vollständig.
Troubleshooting
| Symptom | Ursache und Lösung |
|---|---|
Container startet ständig neu, Log: FATAL: ENCRYPTION_KEY does not match /app/server/data/.encryption_key. | In der .env steht ein anderer Schlüssel als beim ersten Start. TREK verweigert den Start, damit die gespeicherten Geheimnisse lesbar bleiben. Ursprünglichen Wert zurücksetzen und docker compose up -d. Ein echter Schlüsselwechsel läuft über scripts/migrate-encryption.ts. |
| Login klappt, nach dem Neuladen wieder Anmeldeseite | Zugriff über HTTP, das Secure-Cookie wird verworfen. Reverse Proxy mit TLS davor schalten (Schritt 4). COOKIE_SECURE=false ist nur ein Notbehelf für Tests im LAN. |
| Nach dem Update startet TREK nicht, Log nennt einen Pfad | Kein Platz für die Datenbankkopie oder Datenordner schreibgeschützt. Platz schaffen und neu starten. |
exec /usr/bin/dumb-init: operation not permitted | Docker aus Snap verträgt no-new-privileges nicht. Docker aus dem offiziellen Repository installieren. |
Restore meldet This backup was made by a newer TREK version. | Erst TREK auf die Version des Backups aktualisieren, dann einspielen. |
Den Schlüsselfehler haben wir bewusst provoziert: Neustartschleife, Port ohne Antwort. Mit dem alten Wert lief TREK sofort wieder mit allen Daten.
Häufige Fragen
Reicht das eingebaute Backup allein?
Für Datenbank und Uploads ja, der Restore auf einer leeren Instanz hat im Test funktioniert. Den ENCRYPTION_KEY müssen Sie aber separat sichern, wenn Sie ihn per .env setzen. Außerdem liegen die ZIPs auf demselben Datenträger; kopieren Sie sie regelmäßig auf ein zweites System.
Was passiert, wenn der Schlüssel verloren geht?
Laut Wiki bleiben Reisen, Orte und Benutzer erhalten, verschlüsselte Einstellungen wie API-Schlüssel, SMTP-Passwort, OIDC-Secret und TOTP-Geheimnisse werden unlesbar und müssen neu eingetragen werden.
Sollte ich latest verwenden?
latest springt auch über Hauptversionen mit Datenbankmigration. Für Produktivbetrieb ist ein voller Versions-Tag wie 5.0.0 oder der Minor-Tag 5.0 die ruhigere Wahl; Sie aktualisieren dann bewusst nach einem Backup.
Fazit
TREK 5.0 lässt sich mit einer einzigen, bereits gehärteten Compose-Datei betreiben und bringt eine brauchbare eingebaute Sicherung mit. Der Weg von 4.3.4 auf 5.0.0 lief im Test ohne Handarbeit, die automatische Datenbankkopie ist ein echter Gewinn. Die beiden Stolpersteine sind betrieblicher Natur: Ohne HTTPS bleibt niemand angemeldet, und ohne gesicherten ENCRYPTION_KEY startet eine wiederhergestellte Instanz nicht.
Weiterführende Anleitungen und Quellen
- Docker Compose unter Linux: Grundlage für Selfhosting
- Docker Compose absichern: Secrets, Healthchecks, Non-Root
- Caddy als Reverse Proxy mit automatischem HTTPS
- rustic mit Docker Compose: Backups auslagern
- TREK auf GitHub (liketrek/TREK)
- Release-Notes TREK 5.0.0
- TREK-Wiki: Install Docker Compose
- TREK-Wiki: Updating
- TREK-Wiki: Backups
- TREK-Wiki: Encryption Key Rotation


