Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Sicherheit & Datenschutz 05.07.2026 · 10 min Lesezeit

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.

Logto mit Docker installieren: Moderne Auth Infrastruktur mit Docker Container, OpenID Connect, OAuth 2.1, Multi Tenancy, Single Sign On, Benutzerverwaltung, Rollen und sicherer Authentifizierung für Self Hosting und Unternehmensanwendungen.

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

  1. 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.
  2. Mindestens 1 GB RAM frei für Logto-Core und PostgreSQL zusammen; empfohlen sind 2 GB für den Produktivbetrieb.
  3. Freie Ports 3001 und 3002 auf dem Host.
  4. Ein Texteditor für .env und compose.yaml sowie curl zur Verifikation.
  5. 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.
  6. Optional: openssl zur 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/logto

Wer 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 32

Verifizieren: 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: local

Wichtige Details zu dieser Konfiguration:

  1. Healthcheck mit -U logto -d logto: Das offizielle Compose nutzt pg_isready ohne Parameter – das meldet „healthy", obwohl die Logto-Datenbank noch nicht bereit ist. Der korrekte Parameter verhindert Race Conditions beim DB-Seeding.
  2. Persistentes Volume postgres_data: Ohne dieses Volume gehen alle Daten bei docker compose down verloren. Das ist der häufigste Datenverlust-Fehler beim Logto-Betrieb.
  3. 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.
  4. 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 -d

Beim 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 logto

Erfolgreiches Seeding erkennst du an einer Ausgabe wie Created default sign-in experience oder Seed data already exists, skipping.

Verifizieren:

docker compose ps

Erwartete 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-configuration

Erwartete 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.

BereichURL (lokal)Funktion
OIDC Discoveryhttp://localhost:3001/oidc/.well-known/openid-configurationOIDC-Metadaten, Issuer, Endpunkte
Management APIhttp://localhost:3001/apiREST-API für Usermanagement, Apps, Connectors
Admin Consolehttp://localhost:3002Web-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 -d

Achtung: 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-configuration

Erwartete 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 -d

Fü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:

EigenschaftWert
Image (primär)svhd/logto:latest (Docker Hub)
Image (alternativ)ghcr.io/logto-io/logto:latest (GHCR)
Image-Größeca. 288 MB
Port Core Service3001 (OIDC, Management API, Sign-in-Flow)
Port Admin Console3002 (Web-UI)
Datenbank (Pflicht)PostgreSQL 14+
RedisOptional (nur Multi-Instanz)
Volume (Pflicht)postgres_data:/var/lib/postgresql/data
LizenzMozilla Public License 2.0
Aktuelle Versionv1.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

  1. 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: Entweder http://localhost:3002 verwenden oder HTTPS per Reverse Proxy einrichten.
  2. Sign-in schlägt fehl hinter Nginx/Traefik: TRUST_PROXY_HEADER=1 ist nicht gesetzt, oder der Proxy sendet keinen X-Forwarded-Proto: https-Header. Beide Bedingungen müssen erfüllt sein.
  3. Postgres-Healthcheck schlägt fehl / Logto startet nicht: Das offizielle Compose nutzt pg_isready ohne -U logto -d logto-Parameter. Ohne diese Parameter meldet pg_isready „healthy", obwohl die Logto-Datenbank noch nicht bereit ist. Diese Anleitung hat den korrekten Healthcheck bereits integriert.
  4. Datenverlust nach docker compose down: Kein persistentes Volume definiert. Fix: Sicherstellen, dass volumes: postgres_data: ... in der compose.yaml und im postgres-Service definiert ist.
  5. OIDC Token-Validierungsfehler nach Domain-Wechsel: LOGTO_ENDPOINT wurde 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.
  6. CORS-Fehler bei API-Zugriffen: LOGTO_ADMIN_ENDPOINT stimmt 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.
  7. PgBouncer / Connection-Pooler-Fehler: DATABASE_STATEMENT_TIMEOUT=DISABLE_TIMEOUT in der .env setzen, wenn PgBouncer vorgelagert ist.
  8. Management API liefert 404: Community-Tutorials referenzieren oft Cloud-URLs ([tenant-id].logto.app/api). Bei OSS lautet der Endpunkt https://[eigene-domain]/api bzw. http://localhost:3001/api.
  9. Air-Gapped-Umgebung – HaveIBeenPwned-Fehler beim Seeding: --disable-admin-pwned-password-check an das DB-Seeding-Kommando im Entrypoint anhängen.
  10. Invalid ID Token ohne erkennbaren Grund: Uhrzeitabweichung zwischen Server und Client. NTP aktivieren: timedatectl set-ntp true (systemd) oder systemctl 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

  1. Docker Compose: Multi-Container-Stacks aufbauen – Grundlagenwissen zu Compose-Syntax, Netzwerken und Volumes
  2. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only – Produktionshärtung für Compose-Stacks
  3. Single Sign-On für den Self-Hosted-Stack: Authentik vs. Authelia – Vergleich der SSO-Alternativen mit Traefik Forward-Auth
  4. MySQL & PostgreSQL Backup automatisieren mit cron – pg_dump, Rotation und Cloud-Sync für PostgreSQL
  5. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten
  6. 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