Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Docker 26.10.2026 · 10 min Lesezeit

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

Titelbild der Anleitung: Reiseplaner TREK selbst hosten mit Docker Compose, Backup und Update auf 5.0

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, setzt TREK_PLACES_ENABLED=false.
  • Ein Ziel für Backups außerhalb des Servers, etwa ein NAS oder ein Restic-Repository.
EckdatumWert
Imagemauriceboe/trek:5.0.0 (Docker Hub, auch 5.0, 5, latest)
Port3000/tcp (Weboberfläche und API)
Volumes./data:/app/data (Datenbank travel.db, Schlüssel, Backups), ./uploads:/app/uploads
Wichtige EnvENCRYPTION_KEY, TZ, ALLOWED_ORIGINS, ADMIN_EMAIL/ADMIN_PASSWORD (nur Erststart)
Healthcheck/api/health liefert {"status":"ok"}
LizenzAGPL-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.

TREK 5.0 Dashboard mit der angelegten Marker-Reise Dresden 2026, Reisedaten und einem erfassten Ort
Das Dashboard nach dem Login zeigt die nächste Reise mit Zeitraum, Teilnehmern und Orten.

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.

Reiseansicht in TREK mit Tagesplan links, Karte von Dresden in der Mitte und dem Marker-Ort Frauenkirche in der Ortsliste rechts
Die Reiseansicht: Tagesplan, Karte und Ortsliste. Der per API angelegte Marker-Ort erscheint auf der Karte.

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
Adminbereich von TREK, Reiter Backup mit Datensicherung, einem Backup-ZIP sowie den Schaltflächen Backup hochladen und Backup erstellen und der Karte Auto-Backup
Admin, Backup: manuelle Sicherungen, Wiederherstellen per Klick oder Upload und der Zeitplan für Auto-Backups.

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.

Hinweisdialog von TREK nach dem Update mit der Versionsnummer 5.0.0 und den Neuerungen Touren und TREK Studio
Nach dem Update von 4.3.4 begrüßt TREK die Benutzer mit einem Überblick über die Neuerungen in 5.0.0.

Verifizieren: ls data/pre-migrate-* zeigt die Kopie, das Image-Label meldet 5.0.0, und Ihre Reisen sind vollständig.

Troubleshooting

SymptomUrsache 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 AnmeldeseiteZugriff ü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 PfadKein Platz für die Datenbankkopie oder Datenordner schreibgeschützt. Platz schaffen und neu starten.
exec /usr/bin/dumb-init: operation not permittedDocker 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

TREKReiseplanerDocker ComposeSelfhostingBackupSQLiteUpdate