Logto mit Docker installieren: Moderne Auth-Infrastruktur mit OIDC, OAuth 2.1 und Multi-Tenancy
Logto ist die entwicklerfreundliche Open-Source-Alternative zu Auth0 – mit vollständigem OIDC, OAuth 2.1, Multi-Tenancy und Enterprise-SSO. Diese Anleitung zeigt dir, wie du Logto mit Docker Compose in 20 Minuten produktionsbereit aufsetzt, Fallstricke vermeidest und die Admin Console absicherst.

Wer eine eigene SaaS-Anwendung baut oder seinen Self-Hosted-Stack mit zentralem Login ausstattet, steht schnell vor der Frage: Auth selbst bauen oder einem Anbieter anvertrauen? Logto (MPL-2.0, 12.100+ GitHub-Stars, aktuell v1.40.1) ist eine quelloffene Authentication-Infrastruktur, die vollständiges OIDC und OAuth 2.1 implementiert und dabei Multi-Tenancy, Enterprise-SSO über SAML, RBAC und passwortlose Logins mitbringt. Im Unterschied zu Auth0 oder Okta entstehen keine nutzungsabhängigen Kosten, und der Code liegt bei dir. Der Einstieg erfolgt per docker compose – ohne Installationsassistent, ohne externe Abhängigkeit außer PostgreSQL.
Voraussetzungen
- Docker Engine (≥ 24) oder Docker Desktop sowie Docker Compose v2 (Befehl:
docker compose) auf einem Linux-Host, einer VM oder einem NAS mit Docker-Unterstützung – falls du das noch nicht eingerichtet hast, lies zuerst die Docker- und Compose-Grundlageninstallation für Ubuntu/Debian. - Mindestens 1 GB RAM frei für Logto-Core und PostgreSQL zusammen; empfohlen sind 2 GB für den Produktivbetrieb.
- Freie Ports 3001 und 3002 auf dem Host.
- Ein Texteditor für
.envundcompose.yamlsowiecurlzur Verifikation. - Für den Produktivbetrieb: Eine eigene Domain mit HTTPS-Zertifikat und ein Reverse Proxy (Nginx, Traefik oder Caddy). Eine Anleitung dazu findest du unter Caddy als Reverse Proxy mit automatischem HTTPS.
- Optional:
opensslzur Erzeugung eines sicheren KEK-Schlüssels für den Secret Vault.
Schritt 1: Projektordner anlegen
Lege einen dedizierten Ordner für den Logto-Stack an. Alle Konfigurationsdateien landen hier – das erleichtert Updates und Backups erheblich.
mkdir -p /opt/logto
cd /opt/logtoWer lieber im Home-Verzeichnis arbeitet, verwendet ~/logto als Pfad – der Rest der Anleitung bleibt identisch.
Verifizieren: Mit ls /opt/logto prüfen, dass der Ordner existiert. Er ist noch leer – das ist korrekt.
Schritt 2: .env-Datei mit sicheren Secrets anlegen
Logto und PostgreSQL benötigen mehrere Umgebungsvariablen. Lege sie in einer .env-Datei ab, die niemals in ein öffentliches Repository eingecheckt werden darf. Hier die vollständige Vorlage mit Erklärung:
# /opt/logto/.env
# Pflicht: PostgreSQL-Passwort (mind. 20 Zeichen, keine Sonderzeichen die die URL brechen)
POSTGRES_PASSWORD=dein_sicheres_db_passwort_hier
# Produktion: Eigene Domain des Core-Service (bestimmt den OIDC Issuer – VOR dem ersten Start setzen!)
LOGTO_ENDPOINT=https://auth.beispiel.de
# Produktion: Eigene Domain der Admin Console
LOGTO_ADMIN_ENDPOINT=https://admin.auth.beispiel.de
# Produktion: Localhost-Zugang zur Admin Console sperren (auf 1 setzen sobald Reverse Proxy aktiv)
ADMIN_DISABLE_LOCALHOST=
# Optional: AES-256-KEK für Secret Vault (erzeugen mit: openssl rand -base64 32)
SECRET_VAULT_KEK=
# Optional: Statement-Timeout in ms; bei PgBouncer auf DISABLE_TIMEOUT setzen
DATABASE_STATEMENT_TIMEOUT=Für den lokalen Test-Betrieb reicht ein gesetztes POSTGRES_PASSWORD; LOGTO_ENDPOINT und LOGTO_ADMIN_ENDPOINT bleiben leer. Für den Produktivbetrieb müssen beide Domain-Variablen gesetzt sein, bevor der Container das erste Mal startet – nachträgliches Ändern macht alle ausgestellten Tokens ungültig.
Den KEK-Schlüssel erzeugst du einmalig mit:
openssl rand -base64 32Verifizieren: cat /opt/logto/.env zeigt die Datei mit gesetztem POSTGRES_PASSWORD. Stell sicher, dass .env nicht world-readable ist: chmod 600 /opt/logto/.env.
Schritt 3: compose.yaml erstellen
Das offizielle docker-compose.yml auf GitHub ist ausdrücklich nur zur Demonstration gedacht – es fehlen persistente Volumes und sichere Zugangsdaten. Die folgende produktionstaugliche Variante behebt alle bekannten Schwachstellen:
# /opt/logto/compose.yaml
# Produktionsbereit: persistentes Volume, Healthcheck mit User/DB-Parameter,
# sichere Credentials aus .env, alle relevanten Env-Vars konfigurierbar.
services:
logto:
image: svhd/logto:latest
# Alternativ: ghcr.io/logto-io/logto:latest (GitHub Container Registry)
# Pinning auf eine Version empfohlen: svhd/logto:v1.40.1
container_name: logto
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "3001:3001" # Core Service: OIDC-Endpunkte, Management API, Sign-in-Flows
- "3002:3002" # Admin Console: Web-UI zur Konfiguration
entrypoint: ["sh", "-c", "npm run cli db seed -- --swe && npm start"]
environment:
# Pflicht
- DB_URL=postgres://logto:${POSTGRES_PASSWORD}@postgres:5432/logto
- TRUST_PROXY_HEADER=1
# Produktion: eigene Domains (beeinflusst OIDC Issuer!)
- ENDPOINT=${LOGTO_ENDPOINT:-}
- ADMIN_ENDPOINT=${LOGTO_ADMIN_ENDPOINT:-}
# Optional
- ADMIN_DISABLE_LOCALHOST=${ADMIN_DISABLE_LOCALHOST:-}
- SECRET_VAULT_KEK=${SECRET_VAULT_KEK:-}
- DATABASE_STATEMENT_TIMEOUT=${DATABASE_STATEMENT_TIMEOUT:-}
postgres:
image: postgres:17-alpine
container_name: logto-db
restart: unless-stopped
user: postgres
environment:
POSTGRES_USER: logto
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: logto
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U logto -d logto"]
interval: 5s
timeout: 5s
retries: 10
start_period: 30s
volumes:
postgres_data:
driver: localWichtige Details zu dieser Konfiguration:
- Healthcheck mit
-U logto -d logto: Das offizielle Compose nutztpg_isreadyohne Parameter – das meldet „healthy", obwohl die Logto-Datenbank noch nicht bereit ist. Der korrekte Parameter verhindert Race Conditions beim DB-Seeding. - Persistentes Volume
postgres_data: Ohne dieses Volume gehen alle Daten beidocker compose downverloren. Das ist der häufigste Datenverlust-Fehler beim Logto-Betrieb. - Entrypoint mit
--swe: Das Flag ist ein Workaround für PostgreSQL-Lokalisierungskompatibilität und muss unverändert übernommen werden. Das Seeding ist idempotent – es überspringt sich selbst, wenn die Datenbank bereits initialisiert ist. TRUST_PROXY_HEADER=1: Immer setzen, sobald Nginx, Traefik oder ein anderer Reverse Proxy vorgelagert ist – sonst schlägt der HTTPS-Sign-in-Flow fehl.
Schritt 4: Stack starten
Starte alle Container im Hintergrund:
cd /opt/logto
docker compose up -dBeim ersten Start zieht Docker die Images herunter (Logto: ca. 288 MB, PostgreSQL: ca. 50 MB). Danach wartet der Logto-Container auf den PostgreSQL-Healthcheck, bevor er das Datenbank-Seeding startet. Das dauert typischerweise 30–60 Sekunden.
Laufende Logs beobachten:
docker compose logs -f logtoErfolgreiches Seeding erkennst du an einer Ausgabe wie Created default sign-in experience oder Seed data already exists, skipping.
Verifizieren:
docker compose psErwartete Ausgabe (beide Container Up, postgres mit healthy):
NAME IMAGE STATUS
logto svhd/logto:latest Up 2 minutes
logto-db postgres:17-alpine Up 2 minutes (healthy)Anschließend den Core-Service per curl prüfen:
curl -I http://localhost:3001/oidc/.well-known/openid-configurationErwartete Antwort: HTTP/1.1 200 OK. Dieser Endpunkt ist der OIDC Discovery-Endpunkt – wenn er antwortet, funktioniert der Core-Service korrekt.
Schritt 5: Admin-Account einrichten
Öffne im Browser http://localhost:3002. Beim allerersten Aufruf zeigt Logto einen Einrichtungsassistenten zur Erstellung des Admin-Accounts.
Wichtig: Die OSS-Version erlaubt nur einen einzigen Admin-Account. Dieser Schritt lässt sich nicht wiederholen – wähle eine sichere E-Mail-Adresse und ein starkes Passwort. Nach der Einrichtung gelangst du zur Admin Console mit dem vollständigen Dashboard für Applications, Connectors, Users, Enterprise SSO und RBAC.
| Bereich | URL (lokal) | Funktion |
|---|---|---|
| OIDC Discovery | http://localhost:3001/oidc/.well-known/openid-configuration | OIDC-Metadaten, Issuer, Endpunkte |
| Management API | http://localhost:3001/api | REST-API für Usermanagement, Apps, Connectors |
| Admin Console | http://localhost:3002 | Web-UI für die gesamte Konfiguration |
Verifizieren: Nach dem Login siehst du das Logto-Dashboard. Unter „Applications" kannst du eine erste Test-Application anlegen. Unter „Users" erscheint dein Admin-Account. Die Admin Console ist unter http://localhost:3002 erreichbar – nicht über eine IP-Adresse oder einen Hostnamen ohne HTTPS, da der Browser sonst die Web Crypto API blockiert (Fehler: Crypto.subtle unavailable).
Schritt 6: Reverse Proxy und HTTPS einrichten (Produktion)
Für den Produktivbetrieb müssen beide Ports (3001 und 3002) hinter einem HTTPS-Reverse-Proxy liegen. Eine vollständige Anleitung für Nginx mit TLS findest du unter Nginx als Reverse Proxy mit TLS manuell einrichten. Für automatisches HTTPS ohne Zertifikatsverwaltung empfiehlt sich Traefik als Docker-Reverse-Proxy.
Ein minimales Nginx-Server-Block-Beispiel für den Core-Service:
server {
listen 443 ssl;
server_name auth.beispiel.de;
ssl_certificate /etc/letsencrypt/live/auth.beispiel.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.beispiel.de/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Pflicht: Logto erkennt HTTPS-Kontext über diesen Header
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
}
}Derselbe Block wird für admin.auth.beispiel.de mit proxy_pass http://127.0.0.1:3002 benötigt. Danach in der .env die Domain-Variablen setzen und den Stack neu starten:
# .env anpassen:
# LOGTO_ENDPOINT=https://auth.beispiel.de
# LOGTO_ADMIN_ENDPOINT=https://admin.auth.beispiel.de
# ADMIN_DISABLE_LOCALHOST=1
docker compose down
docker compose up -dAchtung: Wenn LOGTO_ENDPOINT vorher nicht gesetzt war (lokaler Test), sind alle bisherigen Tokens ungültig. Bei einem Neuaufbau von Grund auf ist das kein Problem.
Verifizieren:
curl -I https://auth.beispiel.de/oidc/.well-known/openid-configurationErwartete Antwort: HTTP/2 200. Im JSON der Antwort prüfen, ob "issuer" auf https://auth.beispiel.de/oidc zeigt. Falsche Issuer-URL ist die häufigste Ursache für Token-Validierungsfehler in Produktivsystemen.
Schritt 7: Updates und Backup
Logto aktualisieren – Datenbankmigrationen laufen automatisch beim Start:
cd /opt/logto
# Vorher Datenbank sichern
docker exec logto-db pg_dump -U logto logto > /opt/logto/backup_$(date +%Y%m%d).sql
# Update durchführen
docker compose pull
docker compose up -dFür automatisierte PostgreSQL-Backups bietet sich ein Cronjob mit pg_dump an – eine vollständige Anleitung dazu liefert die Anleitung zum Automatisieren von PostgreSQL-Backups.
Für die Eckdaten des Stacks auf einen Blick:
| Eigenschaft | Wert |
|---|---|
| Image (primär) | svhd/logto:latest (Docker Hub) |
| Image (alternativ) | ghcr.io/logto-io/logto:latest (GHCR) |
| Image-Größe | ca. 288 MB |
| Port Core Service | 3001 (OIDC, Management API, Sign-in-Flow) |
| Port Admin Console | 3002 (Web-UI) |
| Datenbank (Pflicht) | PostgreSQL 14+ |
| Redis | Optional (nur Multi-Instanz) |
| Volume (Pflicht) | postgres_data:/var/lib/postgresql/data |
| Lizenz | Mozilla Public License 2.0 |
| Aktuelle Version | v1.40.1 (29. Mai 2026) |
Verifizieren:
docker compose ps
# Beide Container müssen Status "Up" zeigen.
docker compose logs --tail=20 logto
# Keine Fehler zu Image/Port/Volume/Env.Troubleshooting / Typische Fehler
- Admin Console zeigt „Crypto.subtle unavailable": Die Web Crypto API funktioniert nur in sicheren Kontexten. Ursache ist ein Aufruf über HTTP mit IP-Adresse statt
localhost. Fix: Entwederhttp://localhost:3002verwenden oder HTTPS per Reverse Proxy einrichten. - Sign-in schlägt fehl hinter Nginx/Traefik:
TRUST_PROXY_HEADER=1ist nicht gesetzt, oder der Proxy sendet keinenX-Forwarded-Proto: https-Header. Beide Bedingungen müssen erfüllt sein. - Postgres-Healthcheck schlägt fehl / Logto startet nicht: Das offizielle Compose nutzt
pg_isreadyohne-U logto -d logto-Parameter. Ohne diese Parameter meldetpg_isready„healthy", obwohl die Logto-Datenbank noch nicht bereit ist. Diese Anleitung hat den korrekten Healthcheck bereits integriert. - Datenverlust nach
docker compose down: Kein persistentes Volume definiert. Fix: Sicherstellen, dassvolumes: postgres_data: ...in dercompose.yamlund impostgres-Service definiert ist. - OIDC Token-Validierungsfehler nach Domain-Wechsel:
LOGTO_ENDPOINTwurde nach dem ersten Start geändert. Der OIDC Issuer ist unveränderlich – ein Wechsel erfordert einen kompletten Neuaufbau der Instanz. Immer vor dem ersten Start korrekt setzen. - CORS-Fehler bei API-Zugriffen:
LOGTO_ADMIN_ENDPOINTstimmt nicht exakt mit der anfragenden Origin überein (z. B. abschließender Slash, http statt https). Exakt mit Schema und ohne abschließenden Slash setzen:https://admin.auth.beispiel.de. - PgBouncer / Connection-Pooler-Fehler:
DATABASE_STATEMENT_TIMEOUT=DISABLE_TIMEOUTin der.envsetzen, wenn PgBouncer vorgelagert ist. - Management API liefert 404: Community-Tutorials referenzieren oft Cloud-URLs (
[tenant-id].logto.app/api). Bei OSS lautet der Endpunkthttps://[eigene-domain]/apibzw.http://localhost:3001/api. - Air-Gapped-Umgebung – HaveIBeenPwned-Fehler beim Seeding:
--disable-admin-pwned-password-checkan das DB-Seeding-Kommando im Entrypoint anhängen. - Invalid ID Token ohne erkennbaren Grund: Uhrzeitabweichung zwischen Server und Client. NTP aktivieren:
timedatectl set-ntp true(systemd) odersystemctl enable --now chronyd.
Häufige Fragen
Brauche ich Redis für Logto?
Nein. Redis ist ausdrücklich optional und wird nur für den „Central Cache" in Multi-Instanz-Deployments benötigt – also wenn du mehrere Logto-Instanzen hinter einem Load Balancer betreibst. Für eine Einzelinstanz reicht PostgreSQL vollständig aus. Viele Community-Guides nennen Redis fälschlicherweise als Pflichtkomponente.
Wie richte ich den ersten Admin-Account ein?
Nach dem ersten Start von docker compose up -d die Admin Console unter http://localhost:3002 aufrufen. Logto zeigt beim allerersten Aufruf einen Einrichtungsassistenten. Dieser Schritt funktioniert genau einmal – die OSS-Version unterstützt danach keine weiteren Admin-Accounts.
Was ist der Unterschied zwischen Logto OSS und Logto Cloud?
Logto Cloud ist der gehostete Service mit SLA, Multi-Tenant-Management und kostenpflichtigem Pro/Enterprise-Plan. Logto OSS ist selbst gehostet, kostenlos und bietet vollen Code-Zugriff (MPL-2.0). Die Management-API-Basis-URL unterscheidet sich: OSS nutzt die eigene Domain (https://[domain]/api), Cloud nutzt [tenant-id].logto.app/api.
Unterstützt Logto Enterprise SSO wie SAML?
Ja. Logto unterstützt SAML 2.0 und OIDC als Enterprise Connector. Die Konfiguration erfolgt in der Admin Console unter „Enterprise SSO". Unterstützte Provider sind unter anderem Okta, Azure AD/Entra ID und Google Workspace.
Wie aktualisiere ich Logto auf eine neue Version?
Image-Tag in der compose.yaml anpassen (z. B. svhd/logto:v1.40.1), dann docker compose pull && docker compose up -d ausführen. Logto führt Datenbankmigrationen automatisch aus. Vor Updates immer ein PostgreSQL-Backup mit pg_dump erstellen.
Kann ich Logto hinter einem Nginx-Reverse-Proxy betreiben?
Ja. Beide Ports (3001 und 3002) müssen als separate Server-Blöcke konfiguriert werden. Zwingend notwendig sind proxy_set_header X-Forwarded-Proto https und proxy_set_header X-Forwarded-Host $host sowie TRUST_PROXY_HEADER=1 in der Logto-Umgebung – sonst schlägt der Sign-in-Flow fehl.
Welche Architekturen unterstützt das Logto-Image?
Das offizielle Image auf Docker Hub (svhd/logto) ist für linux/amd64 gebaut. Für arm64-Systeme (Apple M-Chips, Raspberry Pi) empfiehlt sich ein Blick auf die GHCR-Tags (ghcr.io/logto-io/logto) oder ein lokaler Build – die offizielle Dokumentation macht hierzu keine explizite Aussage.
Fazit
Logto ist die derzeit entwicklerfreundlichste selbst gehostete Auth-Plattform, wenn es um vollständiges OIDC, OAuth 2.1 und Enterprise-SSO auf Basis von Docker geht. Die Setup-Zeit von 20 Minuten ist realistisch – vorausgesetzt, du setzt LOGTO_ENDPOINT vor dem ersten Start korrekt. Das ist der einzige Punkt, der später nicht ohne Datenverlust korrigierbar ist. Für SaaS-Teams, die Auth0-Kosten sparen wollen, ohne proprietären Protokollen ausgeliefert zu sein, ist Logto eine ernsthafte Alternative. Wer zunächst nur Single Sign-On für seinen Homelab-Stack sucht, findet mit Authentik oder Authelia möglicherweise einen schlankeren Einstieg.
Weiterführende Anleitungen und Quellen
- Docker Compose: Multi-Container-Stacks aufbauen – Grundlagenwissen zu Compose-Syntax, Netzwerken und Volumes
- Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only – Produktionshärtung für Compose-Stacks
- Single Sign-On für den Self-Hosted-Stack: Authentik vs. Authelia – Vergleich der SSO-Alternativen mit Traefik Forward-Auth
- MySQL & PostgreSQL Backup automatisieren mit cron – pg_dump, Rotation und Cloud-Sync für PostgreSQL
- Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten
- Passbolt mit Docker installieren: Team-Passwortmanager
Offizielle Quellen: Logto OSS – Get Started · Logto Deployment and Configuration · logto-io/logto auf GitHub · svhd/logto auf Docker Hub