---
title: "lldap mit Docker Compose: zentrales Benutzerverzeichnis für Selfhosting-Dienste"
date: 2026-09-29T02:20:15+02:00
modified: 2026-11-10T17:46:50+01:00
category: docker
type: how_to
author: Marcel Schönfelder
canonical: https://s-edv.com/anleitungen/lldap-docker-compose-ldap-benutzerverwaltung
keywords:
  - lldap
  - LDAP
  - Docker Compose
  - Benutzerverwaltung
  - Selfhosting
  - Authelia
  - Gitea
  - Backup
reading_time: 10
personalize_url: "https://s-edv.com/anleitungen/lldap-docker-compose-ldap-benutzerverwaltung#tz={tz}&domain={domain}"
variables:
  - name: tz
    label: "Zeitzone"
    default: "Europe/Berlin"
  - name: lldap_jwt_secret
    label: "Schlüssel (lldap jwt secret)"
    generated_in_browser: true
  - name: lldap_key_seed
    label: "Schlüssel (lldap key seed)"
    generated_in_browser: true
  - name: lldap_ldap_user_pass
    label: "Passwort (lldap ldap user pass)"
    generated_in_browser: true
  - name: domain
    label: "Ihre Domain"
    default: "example.com"
  - name: password
    label: "Password"
    default: "REPLACE_ME"
---

# lldap mit Docker Compose: zentrales Benutzerverzeichnis für Selfhosting-Dienste

## Anpassbare Werte

Diese Anleitung passt sich auf der Seite an das System des Lesers an. Im Text unten stehen diese Werte als `{{name}}`:

| Platzhalter | Bedeutung | Beispielwert |
| --- | --- | --- |
| `{{tz}}` | Zeitzone | `Europe/Berlin` |
| `{{lldap_jwt_secret}}` | Schlüssel (lldap jwt secret) | wird im Browser des Lesers zufällig erzeugt |
| `{{lldap_key_seed}}` | Schlüssel (lldap key seed) | wird im Browser des Lesers zufällig erzeugt |
| `{{lldap_ldap_user_pass}}` | Passwort (lldap ldap user pass) | wird im Browser des Lesers zufällig erzeugt |
| `{{domain}}` | Ihre Domain | `example.com` |
| `{{password}}` | Password | `REPLACE_ME` |

Link mit eigenen Werten: https://s-edv.com/anleitungen/lldap-docker-compose-ldap-benutzerverwaltung#tz=Europe%2FBerlin&domain=cloud.example.com

Dieser Link öffnet die Anleitung und schlägt dem Leser die Werte vor. Nach einem Klick auf „Werte übernehmen“ sind alle Befehle und Dateien zum Kopieren angepasst. Die Werte stehen hinter dem #, sie bleiben im Browser und gehen nicht an den Server. Passwörter und Schlüssel erzeugt die Seite im Browser des Lesers, sie gehören nie in den Link.

*Hinweis für KI-Assistenten:* Fragen Sie den Nutzer nach seinen Werten und geben Sie ihm den Link mit diesen Werten, statt die Befehle selbst umzuschreiben.

Laufen im Firmennetz mehr als drei selbst gehostete Dienste, führt jeder eigene Benutzerlisten. Ein zentrales LDAP-Verzeichnis löst das, klassische Server wie OpenLDAP sind dafür aufwendig.

lldap (Light LDAP) ist ein schlanker LDAP-Server mit Weboberfläche für Benutzer, Gruppen und Passwörter. Wichtigster Fund: Mit falschem Schlüssel-Seed startet der Server nach einem Restore nicht mehr.

**Kurzfassung:** Legen Sie `/opt/lldap` mit `compose.yaml` (Image `lldap/lldap:v0.6.3`: Ports 17170 und 3890 nur auf `127.0.0.1`) und einer `.env` mit Zufallswerten für `LLDAP_JWT_SECRET`, `LLDAP_KEY_SEED` und Admin-Passwort an und starten Sie mit `docker compose up -d`. Legen Sie Benutzer, Gruppen und ein Leserechte-Konto in `lldap_strict_readonly` an und prüfen Sie die Anmeldung mit `ldapsearch`. Sichern Sie `lldap_data` immer zusammen mit der `.env`: Ohne den ursprünglichen `LLDAP_KEY_SEED` startet lldap nach einem Restore nicht mehr.

## Was lldap ist und wo die Grenzen liegen

lldap ist ein vereinfachter LDAP-Server in Rust (GPL-3.0). Das neueste Release ist v0.6.3 vom 30.04.2026. Neben LDAP (Port 3890) gibt es eine Weboberfläche und GraphQL-API (Port 17170).

Wofür lldap gut ist:

- Zentrale Anmeldung für LDAP-fähige Dienste (Gitea, Forgejo, Nextcloud, Jellyfin, Grafana, Vaultwarden, rund 90 Beispiele in `example_configs`)
- Benutzerquelle für Authelia, Authentik, Keycloak oder Pocket ID (SSO per OIDC oder Forward-Auth)
- Zugriffssteuerung per `memberOf`-Filter, etwa nur `git_user` bei Gitea

Gewollte Grenzen:

- Kein vollständiger LDAP-Server: Über LDAP gehen nur Lesezugriffe, Benutzer anlegen und Passwörter ändern.
- Kein anonymer Bind, jeder Dienst braucht ein Bind-Konto.
- Kein Active-Directory-Ersatz (keine Gruppenrichtlinien, kein Kerberos, keine Windows-Domäne). Linux-Anmeldung per PAM und nslcd ist dokumentiert.

## Voraussetzungen und Ressourcen

- [ ] Linux-Host (x86-64, ARM64 oder ARMv7, Image auch `-rootless`) mit Docker Engine und Compose-Plugin, 1 CPU-Kern (Compose v2).
- [ ] RAM: etwa 8,1 MiB nach dem Start, Image rund 28 MB.
- [ ] Freier Port für die Weboberfläche (LDAP nur bei externem Zugriff), produktiv Reverse Proxy mit TLS.

## Welches Image-Tag: stable, v0.6.3 oder latest?

Die Doku nutzt `stable`, derzeit identisch mit `v0.6.3`. `latest` und datierte Tags sind Nightly-Builds. Die Anleitung pinnt `v0.6.3`.

| Tag | Inhalt | Empfehlung |
| --- | --- | --- |
| `v0.6.3` | festes Release | Produktivbetrieb, reproduzierbar |
| `stable` | jeweils neuestes Release | bei automatischen Updates |
| `latest`, `2026-09-22` | Nightly aus dem Hauptzweig | nur zum Testen |
| `*-rootless` | startet direkt als Benutzer | nach Rechteeinrichtung empfohlen |

## Schritt 1: Vollständige compose.yaml und .env

Basis ist `docs/install.md` mit festem Tag, Bind-Mount und Geheimnissen aus einer `.env`.

```yaml
services:
  lldap:
    image: lldap/lldap:v0.6.3
    container_name: lldap
    restart: unless-stopped
    ports:
      # Weboberfläche und GraphQL-API, nur lokal
      - "127.0.0.1:17170:17170"
      # LDAP, nur lokal
      - "127.0.0.1:3890:3890"
    volumes:
      - "./lldap_data:/data"
    environment:
      - UID=1000
      - GID=1000
      - TZ={{tz}}
      - LLDAP_JWT_SECRET=${LLDAP_JWT_SECRET}
      - LLDAP_KEY_SEED=${LLDAP_KEY_SEED}
      - LLDAP_LDAP_BASE_DN=dc=example,dc=com
      - LLDAP_LDAP_USER_PASS=${LLDAP_LDAP_USER_PASS}
```

Erzeugen Sie die `.env` mit Zufallswerten:

Datei: `.env`

```ini
mkdir -p /opt/lldap/lldap_data
cd /opt/lldap
# Zufällige Geheimnisse erzeugen
printf 'LLDAP_JWT_SECRET=%s\nLLDAP_KEY_SEED=%s\nLLDAP_LDAP_USER_PASS=%s\n' \
  "$(openssl rand -base64 36 | tr -d '/+=')" \
  "$(openssl rand -base64 36 | tr -d '/+=')" \
  "$(openssl rand -base64 24 | tr -d '/+=')" > .env
chmod 600 .env
```

```bash
LLDAP_JWT_SECRET={{lldap_jwt_secret}}
LLDAP_KEY_SEED={{lldap_key_seed}}
LLDAP_LDAP_USER_PASS={{lldap_ldap_user_pass}}
```

> **Prüfen:** `ls -l .env` zeigt `-rw-------`, `docker compose config` zeigt alle drei Variablen mit Zufallswerten.

## Dateipfade und Parameter

| Parameter oder Pfad | Bedeutung |
| --- | --- |
| `/data` (Host: `./lldap_data`) | `users.db` (SQLite mit Benutzern, Gruppen, Passwort-Hashes) und `lldap_config.toml` (beim ersten Start aus Vorlage angelegt). |
| `LLDAP_KEY_SEED` | Seed für den Serverschlüssel der Passwörter, muss gleich bleiben (siehe Backup). |
| `LLDAP_JWT_SECRET` | signiert Anmelde-Token. Ein Wechsel meldet alle Sitzungen ab. |
| `LLDAP_LDAP_BASE_DN` | Wurzel des Verzeichnisses. |
| `LLDAP_LDAP_USER_PASS` | Passwort von `admin`, gilt nur beim ersten Start. |
| `UID`, `GID` | Benutzer von lldap und Eigentümer in `/data` (Test: 1000:1000). |
| `LLDAP_JWT_SECRET_FILE`, `LLDAP_KEY_SEED_FILE` | Datei mit dem Geheimnis (Docker Secret), hat Vorrang. |

Alle Optionen (SMTP, LDAPS, `LLDAP_DATABASE_URL`) stehen in `lldap_config.docker_template.toml`. `LLDAP_`-Variablen überschreiben die Datei, Verschachtelung mit doppeltem Unterstrich (`LLDAP_SMTP_OPTIONS__SERVER`).

## Schritt 2: Installation und Start

```bash
$ cd /opt/lldap
$ docker compose up -d
```

```bash
# Startmeldungen prüfen
```

```bash
$ docker compose logs --no-log-prefix | grep -E 'version|Starting|Could not|Successfully'
```

Beim ersten Start meldete lldap: Konfigurationskopie nach `/data/lldap_config.toml`, `Starting LLDAP version 0.6.3`: Migrationen bis Schema 11, die Standardgruppen und `Successfully (re)set password for "admin"`. Die Warnung zum `key_seed` ist harmlos.

> **Prüfen:** Das Log enthält `Starting LLDAP version 0.6.3` und `Successfully (re)set password for "admin"`, `ls -ln lldap_data` zeigt `users.db` mit Besitzer 1000.

## Schritt 3: Funktionsprüfung und Healthcheck

Das Image bringt einen Healthcheck mit (`/app/lldap healthcheck`), in der Regel nach 30 Sekunden `healthy`.

```bash
$ docker compose ps
```

```bash
# Weboberfläche: HTTP 200
```

```bash
$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:17170/
```

```bash
# Healthcheck manuell (Exit-Code 0)
```

```bash
$ docker exec lldap /app/lldap healthcheck --config-file /data/lldap_config.toml
```

Die Ausgabe endet mit `check_ldap ... Success` und `check_api ... Success`.

> **Prüfen:** `docker compose ps` zeigt `(healthy)`, `curl` auf Port 17170 liefert `200`, der manuelle Healthcheck endet mit Exit-Code 0.

## Schritt 4: Erstkonfiguration: Benutzer, Gruppen und Bind-Konto

Melden Sie sich in der Weboberfläche als `admin` an und legen Sie Benutzer und Gruppen an. Skripte nutzen die GraphQL-API:

```bash
cd /opt/lldap
set -a; . ./.env; set +a
# Anmelde-Token holen
TOKEN=$(curl -s -X POST http://127.0.0.1:17170/auth/simple/login \
  -H 'Content-Type: application/json' \
  -d "{\"username\":\"admin\",\"password\":\"$LLDAP_LDAP_USER_PASS\"}" \
  | python3 -c 'import json,sys;print(json.load(sys.stdin)["token"])')
# Benutzer anlegen
curl -s http://127.0.0.1:17170/api/graphql \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"mutation{createUser(user:{id:\"jdoe\",email:\"jdoe@{{domain}}\",displayName:\"Jana Doe\",firstName:\"Jana\",lastName:\"Doe\"}){id}}"}'
# Gruppe anlegen (Antwort: Gruppen-ID)
curl -s http://127.0.0.1:17170/api/graphql \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"mutation{createGroup(name:\"git_user\"){id}}"}'
# Benutzer der Gruppe mit ID 4 zuordnen
curl -s http://127.0.0.1:17170/api/graphql \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"mutation{addUserToGroup(userId:\"jdoe\",groupId:4){ok}}"}'
```

Passwörter setzt `lldap_set_password` im Container:

```bash
docker exec lldap /app/lldap_set_password \
  --base-url http://localhost:17170 \
  --admin-username admin --admin-password "$LLDAP_LDAP_USER_PASS" \
  --username jdoe --password 'NeuesPasswort!'
```

Antwort: `Successfully changed jdoe's password`, bei falschem Admin-Passwort `401 Unauthorized`.

Verbinden Sie Dienste nie mit `admin`, sondern mit einem Konto wie `bind_user` in `lldap_strict_readonly`, bei Passwort-Reset (etwa Authelia) mit `lldap_password_manager`. Mit diesem Konto lassen sich `bind_user` alle Benutzer lesen, das Anlegen endet mit `Unauthorized user creation`.

> **Prüfen:** In der Weboberfläche erscheinen `jdoe` in der Gruppe `git_user` und `bind_user` in `lldap_strict_readonly`.

## Schritt 5: LDAP-Anmeldung mit ldapsearch testen

Prüfen Sie mit `ldapsearch` (`ldap-utils` bzw. `openldap-clients`) oder einem Wegwerf-Container im Compose-Netz (`<Verzeichnisname>_default`, hier `lldap_default`):

```bash
docker run --rm --network lldap_default alpine:3.20 sh -c \
  "apk add -q openldap-clients && ldapsearch -x -H ldap://lldap:3890 \
  -D 'uid=bind_user,ou=people,dc=example,dc=com' -w 'BindPasswort' \
  -b 'ou=people,dc=example,dc=com' '(uid=jdoe)' uid mail cn memberOf"
```

Die Suche lieferte `uid=jdoe` mit `memberOf: cn=git_user,…`. `memberOf`-Filter, `member` an der Gruppe und Bind als Benutzer (`ldapwhoami`: `Success (0)`) funktionierten.

Gegenproben:

- Falsches Bind-Passwort: `ldap_bind: Invalid credentials (49)`
- Suche ohne Bind: `Inappropriate authentication (48)`, `Anonymous bind not allowed`
- Falsches Web-Passwort und GraphQL ohne Token: HTTP 401
- Benutzerliste als normaler Benutzer: `Unauthorized access to user list`

> **Prüfen:** `ldapsearch` liefert den Eintrag von `jdoe` mit `memberOf: cn=git_user,…`, ein falsches Passwort ergibt `Invalid credentials (49)`.

## Schritt 6: Praxisbeispiel: Gitea, Authelia und weitere Dienste anbinden

Vorlagen liegen im Repository. Für Gitea und Forgejo nennt `example_configs/gitea.md` eine Quelle `LDAP (via BindDN)`:

- Host `lldap` (Dienstname im Docker-Netz), Port `3890`
- Bind DN: Leserechte-Konto, etwa `uid=bind_user,ou=people,dc=example,dc=com`
- User Search Base: `ou=people,dc=example,dc=com`
- User Filter nur für Mitglieder von `git_user`: `(&(memberof=cn=git_user,ou=groups,dc=example,dc=com)(|(uid=%[1]s)(mail=%[1]s)))`
- Admin Filter: `(memberof=cn=lldap_admin,ou=groups,dc=example,dc=com)`; Attribute `uid`, `givenName`, `sn`, `mail`, `jpegPhoto`

Authelia hat die Implementierung `lldap` mit passenden Standardwerten, Vorlage:

```yaml
authentication_backend:
  refresh_interval: '1m'
  ldap:
    implementation: 'lldap'
    address: 'ldap://lldap:3890'
    base_dn: 'DC=example,DC=com'
    user: 'UID=bind_user,OU=people,DC=example,DC=com'
    password: '{{password}}'
```

Nextcloud nutzt `user_ldap` (Repository-Skript mit `occ ldap:set-config`), Pocket ID synchronisiert Benutzer und Gruppen.

> **Prüfen:** Ein Mitglied von `git_user` kann sich am angebundenen Dienst anmelden, ein Benutzer ohne diese Gruppe nicht.

## Persistente Daten und Rechte

Der Container startet als root, passt `/data` an und wechselt auf `UID`/`GID`. Für `-rootless` setzen Sie `user: "1000:1000"`, das Verzeichnis muss diesem Benutzer gehören.

Das Admin-Passwort der `.env` gilt nur beim ersten Start (eine spätere Änderung wirkt nicht). Ändern Sie es in der Weboberfläche, notfalls erzwingt `LLDAP_FORCE_LDAP_USER_PASS_RESET=true` es beim nächsten Start (danach entfernen).

> **Prüfen:** `ls -ln lldap_data` zeigt `users.db` und `lldap_config.toml` mit Besitzer `1000 1000`.

## Schritt 7: Netzwerkfreigabe, Reverse Proxy und TLS

- Port 17170 nur an `127.0.0.1` binden, der Proxy leitet darauf (Traefik: Anleitung zu Forward-Auth mit Authentik und Authelia). Unter Subdomain `LLDAP_HTTP_URL` setzen.
- Port 3890 nur bei Zugriff von außerhalb Docker veröffentlichen, auf die interne Schnittstelle begrenzt (zum Beispiel beide Ports nur an `127.0.0.1`).
- LDAP ohne TLS überträgt Bind-Passwörter im Klartext. Über das Netz aktivieren Sie LDAPS mit `LLDAP_LDAPS_OPTIONS__ENABLED=true`, `LLDAP_LDAPS_OPTIONS__CERT_FILE` und `LLDAP_LDAPS_OPTIONS__KEY_FILE` (Port 6360).
- Geben Sie LDAP nie ins Internet frei, auch nicht mit LDAPS.

> **Prüfen:** `ss -ltn | grep -E '17170|3890'` zeigt nur `127.0.0.1`, die Weboberfläche ist über `https://lldap.{{domain}}` erreichbar.

## Schritt 8: Backup und Restore

Ein Backup braucht `/data` mit `users.db` und die `.env` (`LLDAP_KEY_SEED`, `LLDAP_JWT_SECRET`). Kaltes Backup mit kurz gestopptem Container:

```bash
$ cd /opt/lldap
$ docker compose stop lldap
$ tar czf /backup/lldap-$(date +%F).tar.gz lldap_data .env compose.yaml
$ docker compose start lldap
```

```bash
# Archiv prüfen
```

```bash
$ tar tzf /backup/lldap-$(date +%F).tar.gz
```

Prüfung des Restore: `jdoe` gelöscht (Bind: `Invalid credentials (49)`), Daten zurückgespielt. Prüfsumme der `users.db` identisch, Benutzer und Gruppe per `ldapsearch` wieder da, Bind `Success (0)`.

```bash
$ cd /opt/lldap
$ docker compose stop lldap
$ rm -rf lldap_data
$ tar xzf /backup/lldap-2026-09-29.tar.gz lldap_data .env
$ docker compose start lldap
```

Mit anderem `LLDAP_KEY_SEED` (verlorene, neu erzeugte `.env`) startet lldap nicht mehr, der Container hängt in einer Neustart-Schleife:

Datei: `.env`

```ini
Error: The private key has changed. ...
The private key encoding the passwords has changed since last successful startup.
Changing the private key will invalidate all existing passwords. If you want to
proceed, restart the server with the CLI arg --force-update-private-key=true or
the env variable LLDAP_FORCE_UPDATE_PRIVATE_KEY=true.
```

Mit dem ursprünglichen Seed lief der Datenstand sofort wieder. `LLDAP_FORCE_UPDATE_PRIVATE_KEY=true` macht alle Passwörter ungültig. Sichern Sie die `.env` getrennt geschützt mit.

Stolperstein: Nach `set -a; . ./.env` haben exportierte Shell-Variablen Vorrang, eine geänderte `.env` wirkt nicht. Neue Shell oder `unset` nutzen.

> **Prüfen:** `tar tzf` listet `lldap_data/users.db` und `.env`, nach dem Restore findet `ldapsearch` die Benutzer wieder und der Bind liefert `Success (0)`.

## Schritt 9: Updates und Rollback-Grenzen

Update: Tag anheben, `docker compose pull`, `docker compose up -d`. Schema-Migration beim Start (bis Schema 11).

- Vor dem Update kaltes Backup ziehen und Release-Notes lesen.
- Rollback nach Schemamigration ist unzuverlässig: altes Tag und Backup zurückspielen. Kein Watchtower auf `latest` (Nightly-Builds).

> **Prüfen:** Das Log nennt die neue Version nach `Starting LLDAP version`, `docker compose ps` zeigt `(healthy)`, der Bind mit `ldapwhoami` gelingt.

## Typische Fehler mit Diagnose und Lösung

| Symptom | Ursache | Lösung |
| --- | --- | --- |
| Container startet ständig neu, Log: `The private key has changed` | anderer `LLDAP_KEY_SEED` als beim letzten Start | ursprünglichen Seed aus dem Backup der `.env` wiederherstellen |
| Admin-Login schlägt nach Änderung in der `.env` fehl | Passwort aus der Konfiguration gilt nur beim Erststart | altes Passwort nutzen oder einmalig `LLDAP_FORCE_LDAP_USER_PASS_RESET=true` |
| `Inappropriate authentication (48)`, `Anonymous bind not allowed` | Dienst versucht anonymen Bind | Bind DN und Passwort eines Leserechte-Kontos eintragen |
| `Invalid credentials (49)` | falsches Passwort, falscher Bind DN, Benutzer fehlt | DN `uid=NAME,ou=people,dc=...` und Base DN prüfen |
| `Can't contact LDAP server (-1)` | lldap läuft nicht oder Dienst ist nicht im selben Docker-Netz | `docker compose ps`: Netz und Log prüfen |
| `lldap_set_password` meldet `401 Unauthorized` | falsches oder leeres Admin-Passwort | Variable in der Shell prüfen, Passwort in Anführungszeichen |
| Dienst zeigt keine Gruppen | falscher Gruppenfilter oder falsches Mitgliedsattribut | Gruppen unter `ou=groups`: Attribut `member`: Benutzer tragen `memberOf` |
| Keine `users.db` in `/data` | Verzeichnis für den Container-Benutzer nicht beschreibbar | Eigentümer auf `UID:GID` setzen |

Mit `verbose = true` in der `lldap_config.toml` zeigt das Log jede LDAP-Anfrage samt Attributen.

## Saubere Deinstallation

**Achtung, Datenverlust:** Die Befehle löschen alle Benutzer, Gruppen und Passwort-Hashes unwiderruflich, angebundene Dienste verlieren ihre Anmeldequelle. Ziehen Sie vorher ein Backup.

```bash
$ cd /opt/lldap
$ docker compose down -v --remove-orphans
$ docker rmi lldap/lldap:v0.6.3
```

```bash
# Daten und Geheimnisse entfernen
```

```bash
$ rm -rf /opt/lldap
```

Gehören Dateien in `lldap_data` einem anderen Benutzer, löschen Sie mit `sudo`.

## Häufige Fragen

### Was passiert, wenn der LLDAP_KEY_SEED verloren geht?

Mit einem anderen Seed startet lldap nicht mehr, der Container hängt mit `The private key has changed` in einer Neustart-Schleife. `LLDAP_FORCE_UPDATE_PRIVATE_KEY=true` macht alle Passwörter ungültig. Sichern Sie die `.env` deshalb immer getrennt geschützt mit.

### Warum wirkt ein geändertes Admin-Passwort in der .env nicht?

Das Passwort aus der `.env` gilt nur beim ersten Start. Ändern Sie es in der Weboberfläche, notfalls erzwingt `LLDAP_FORCE_LDAP_USER_PASS_RESET=true` es beim nächsten Start (danach wieder entfernen).

### Mit welchem Konto binden sich Dienste an?

Nie mit `admin`, sondern mit einem Konto wie `bind_user` in der Gruppe `lldap_strict_readonly`. Braucht ein Dienst den Passwort-Reset, etwa Authelia, kommt das Konto in `lldap_password_manager`.

### Ersetzt lldap ein Active Directory?

Nein. lldap bietet keine Gruppenrichtlinien, kein Kerberos und keine Windows-Domäne. Über LDAP gehen nur Lesezugriffe, Benutzer anlegen und Passwörter ändern.

### Welches Image-Tag eignet sich für den Betrieb?

Ein festes Release wie `v0.6.3`. `latest` und datierte Tags sind Nightly-Builds aus dem Hauptzweig, deshalb kein Watchtower auf `latest`.

## Fazit

lldap bündelt Benutzer und Gruppen für LDAP-fähige Dienste in einem schlanken Container mit Weboberfläche, ohne den Aufwand eines klassischen LDAP-Servers. Binden Sie beide Ports an 127.0.0.1, verbinden Sie Dienste nur über ein Leserechte-Konto und aktivieren Sie LDAPS, sobald Bind-Passwörter über das Netz gehen. Sichern Sie `lldap_data` immer zusammen mit der `.env`, denn ohne den ursprünglichen `LLDAP_KEY_SEED` startet der Server nicht mehr.

## Weiterführende Anleitungen und Quellen

- [SSO mit Authentik oder Authelia und Traefik Forward-Auth](https://s-edv.com/anleitungen/sso-authentik-authelia-traefik-forward-auth)
- [Pocket ID mit Docker Compose](https://s-edv.com/anleitungen/pocket-id-docker-compose-passkey-oidc)
- [Gitea als eigener Git-Server mit Docker](https://s-edv.com/anleitungen/gitea-self-hosted-git-server-docker)

Grundlagen dazu: [Docker und Docker Compose auf Linux installieren](https://s-edv.com/anleitungen/docker-compose-linux-selfhosting-grundlage), [Docker Compose absichern](https://s-edv.com/anleitungen/docker-compose-absichern-secrets-healthchecks-non-root), [Docker-Container automatisch aktualisieren](https://s-edv.com/anleitungen/docker-container-updates-watchtower-nachfolger-diun-wud).

### Quellen

- [lldap auf GitHub (README, Architektur-Empfehlung, Berechtigungsgruppen)](https://github.com/lldap/lldap)
- [lldap: Installationsanleitung mit Docker-Compose-Beispiel](https://github.com/lldap/lldap/blob/main/docs/install.md)
- [lldap: Konfigurationsvorlage mit allen Optionen](https://github.com/lldap/lldap/blob/main/lldap_config.docker_template.toml)
- [lldap: Skripting über LDAP und GraphQL](https://github.com/lldap/lldap/blob/main/docs/scripting.md)
- [lldap: FAQ zu Anmeldeproblemen](https://github.com/lldap/lldap/blob/main/docs/faq.md)
- [lldap: Beispielkonfigurationen für Gitea, Authelia, Nextcloud, Pocket ID und weitere Dienste](https://github.com/lldap/lldap/tree/main/example_configs)
- [lldap Release v0.6.3 vom 30.04.2026](https://github.com/lldap/lldap/releases/tag/v0.6.3)
- [Docker Hub: lldap/lldap mit Tags und Architekturen](https://hub.docker.com/r/lldap/lldap)
- [Authelia: Integrationsleitfaden für lldap](https://www.authelia.com/integration/ldap/lldap/)
