Leantime mit Docker Compose: Projektmanagement für kleine Teams selbst hosten
Leantime verbindet Ziele, Projekte und Aufgaben in einer Oberfläche für Teams ohne PM-Ausbildung. Die Anleitung zeigt den Betrieb von Version 3.10.4 mit Docker Compose und MySQL 8.4, die Einrichtung über den Installer, Mailversand per SMTP, Reverse Proxy mit HTTPS sowie Backup und Restore mit Nachweis. Dazu kommen Updates mit Datenbankmigration und typische Fehlerbilder aus dem Praxistest.
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

Viele kleine Teams brauchen kein schwergewichtiges Projektmanagement mit Ressourcenplanung und Gantt-Pflicht, aber mehr als eine geteilte Aufgabenliste. Leantime setzt genau dort an: Das Open-Source-Werkzeug verbindet Ziele, Projekte, Meilensteine und Aufgaben in einer Oberfläche, die sich ausdrücklich an Menschen ohne PM-Ausbildung richtet. Laut Projektbeschreibung wurde sie mit Blick auf ADHS, Legasthenie und Autismus gestaltet. Diese Anleitung zeigt, wie Sie Leantime 3.10.4 mit Docker Compose und MySQL 8.4 betreiben, den Installer durchlaufen, Mails über SMTP versenden, Daten sichern und nachweislich wiederherstellen sowie Updates sauber einspielen.
Voraussetzungen
Im Test belegte der Leantime-Container nach Installation, Projektanlage und mehreren Aufgaben rund 130 MB RAM, MySQL rund 460 MB.
- Linux-Server oder VM mit 2 CPU-Kernen und 2 bis 4 GB RAM; 4 GB lassen Luft für Reverse Proxy und Backups.
- 10 GB freier Speicher für Images, Datenbank und Dateianhänge, mehr bei vielen Uploads.
- x86_64 oder ARM: Das Image
3.10.4ist auf Docker Hub füramd64,arm64undarmgebaut. - Docker Engine mit Compose v2, ein Domainname mit DNS-Eintrag und ein Reverse Proxy für HTTPS.
- Ein SMTP-Konto für Einladungen, Passwort-Rücksetzung und Benachrichtigungen.
Zur Einordnung: S-EDV hat bereits Anleitungen zu Planka als schlankem Kanban-Board, zu Plane für Software-Teams und zu OpenProject mit Gantt und klassischer Projektplanung. Leantime liegt dazwischen: mehr Struktur als Planka, weniger Formalismus als OpenProject, mit Zielen, Ideen und Aufgaben am selben Ort. Die Software steht unter AGPL-3.0; das Repository zählte am 09.10.2026 11.775 Sterne, die aktuelle Version 3.10.4 erschien am 05.10.2026.
| Eckdaten | Wert |
|---|---|
| Image | leantime/leantime:3.10.4 (Docker Hub), Datenbank mysql:8.4 |
| Port | 8080 im Container (Nginx), Healthcheck im Image: curl -f http://localhost:8080 |
| Volumes | db_data, userfiles, public_userfiles, plugins, logs |
| Wichtige Variablen | LEAN_APP_URL, LEAN_DB_*, LEAN_SESSION_PASSWORD, LEAN_SESSION_SECURE, LEAN_EMAIL_* |
| Benutzer im Container | www-data (UID 1000), PHP 8.3 |
| Lizenz | AGPL-3.0 |
Schritt 1: compose.yaml und .env anlegen
Grundlage ist die Compose-Datei aus dem offiziellen Repository Leantime/docker-leantime. Geändert sind: kein veraltetes version, kein fester container_name (Datenbank über den Dienstnamen leantime_db) und Image auf 3.10.4 festgeschrieben statt latest. Der Dienst mailpit dient nur zum Testen des Mailversands.
services:
leantime_db:
image: mysql:8.4
restart: unless-stopped
env_file: ./.env
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
leantime:
image: leantime/leantime:${LEAN_VERSION:-3.10.4}
restart: unless-stopped
env_file: ./.env
security_opt:
- no-new-privileges:true
cap_add:
- CAP_CHOWN
- CAP_SETGID
- CAP_SETUID
ports:
- "${LEAN_PORT:-8080}:8080"
volumes:
- public_userfiles:/var/www/html/public/userfiles
- userfiles:/var/www/html/userfiles
- plugins:/var/www/html/app/Plugins
- logs:/var/www/html/storage/logs
depends_on:
leantime_db:
condition: service_healthy
# nur zum Testen, im Betrieb entfernen
mailpit:
image: axllent/mailpit:latest
restart: unless-stopped
ports:
- "8025:8025"
volumes:
db_data:
userfiles:
public_userfiles:
plugins:
logs:
Die .env enthält alle Einstellungen. LEAN_DB_PASSWORD muss exakt MYSQL_PASSWORD entsprechen, LEAN_DB_HOST dem Dienstnamen. LEAN_APP_URL ist die spätere öffentliche Adresse: Leantime baut daraus alle Weiterleitungen, im Test zeigte schon die erste Antwort auf diese Adresse.
LEAN_VERSION=3.10.4
LEAN_PORT=8080
LEAN_APP_URL=https://pm.example.de
LEAN_DEBUG=0
MYSQL_ROOT_PASSWORD=BITTE-ERSETZEN-root
MYSQL_DATABASE=leantime
MYSQL_USER=lean
MYSQL_PASSWORD=BITTE-ERSETZEN-db
LEAN_DB_HOST=leantime_db
LEAN_DB_USER=lean
LEAN_DB_PASSWORD=BITTE-ERSETZEN-db
LEAN_DB_DATABASE=leantime
LEAN_DB_PORT=3306
LEAN_SESSION_PASSWORD=BITTE-ERSETZEN-session
LEAN_SESSION_EXPIRATION=28800
LEAN_SESSION_SECURE=false
LEAN_SITENAME=Leantime
LEAN_LANGUAGE=de-DE
LEAN_DEFAULT_TIMEZONE=Europe/Berlin
LEAN_EMAIL_RETURN=leantime@example.de
LEAN_EMAIL_USE_SMTP=true
LEAN_EMAIL_SMTP_HOSTS=mailpit
LEAN_EMAIL_SMTP_AUTH=false
LEAN_EMAIL_SMTP_AUTO_TLS=false
LEAN_EMAIL_SMTP_SECURE=
LEAN_EMAIL_SMTP_PORT=1025
openssl rand -hex 24
openssl rand -hex 24
openssl rand -hex 32
chmod 600 .env
Zu Rechten: PUID und PGID wirken laut sample.env nur beim eigenen Bauen des Images, das veröffentlichte Image läuft als UID 1000. Mit benannten Volumes wie oben ist nichts weiter nötig.
Verifizieren: docker compose config --quiet gibt nichts aus, und grep -c BITTE-ERSETZEN .env liefert 0.
Schritt 2: Stack starten
mkdir -p /opt/leantime && cd /opt/leantime
# compose.yaml und .env wie oben anlegen
docker compose up -d
docker compose ps
curl -sI http://localhost:8080 | grep -iE 'HTTP|location'
MySQL muss zuerst healthy sein, erst dann startet Leantime. Im Test dauerte das gut 20 Sekunden, danach antwortete Nginx sofort mit einer Weiterleitung auf den Installer:
NAME IMAGE STATUS
leantime-leantime-1 leantime/leantime:3.10.4 Up 2 seconds (health: starting)
leantime-leantime_db-1 mysql:8.4 Up 23 seconds (healthy)
leantime-mailpit-1 axllent/mailpit:latest Up 23 seconds (healthy)
HTTP/1.1 303 See Other
Location: https://pm.example.de/install
Im Container laufen Nginx, PHP-FPM und ein Scheduler, der jede Minute Warteschlangen wie queue:emails abarbeitet.
Verifizieren: Nach etwa 30 Sekunden zeigt docker compose ps beide Hauptdienste als healthy, und docker compose logs leantime | grep RUNNING listet php-fpm, nginx und scheduler.
Schritt 3: Installer und Administratorkonto
Öffnen Sie https://pm.example.de/install. Das Formular legt die Datenbanktabellen an und fragt E-Mail-Adresse, Vor- und Nachname sowie Firma ab. Ein Passwortfeld gibt es hier nicht.

Nach dem Klick auf „Installieren“ leitet Leantime direkt in einen Einrichtungsassistenten. Im ersten Schritt vergeben Sie Name, Rolle und Passwort. Die Regel verlangt mindestens 8 Zeichen mit Groß- und Kleinbuchstaben, Ziffer und Sonderzeichen. Theme, Farbschema und Arbeitszeiten können Sie mit Standardwerten übernehmen. Einzelne Texte bleiben trotz de-DE englisch.
Wichtig: Bis das erste Konto existiert, kann jeder mit Zugriff auf die Adresse die Installation übernehmen. Schließen Sie den Installer deshalb sofort ab.
Verifizieren: Abmelden und unter /auth/login neu anmelden. Mit korrektem Passwort landen Sie auf /dashboard/home, mit falschem wieder auf der Anmeldeseite.
Schritt 4: Erstes Projekt und Aufgaben anlegen
Leantime legt ein persönliches Projekt „My Project“ mit Onboarding-Checkliste an. Erstellen Sie über das Projektmenü ein eigenes Projekt, im Test „Website-Relaunch 2027“, und legen Sie unter „Aufgaben“ per „Add To-Do“ Aufgaben direkt in der passenden Spalte an.

Für Teams ohne PM-Erfahrung lohnt sich ein schlanker Einstieg: zuerst ein Ziel, dann zwei bis drei Meilensteine, danach Aufgaben. Ideen-Boards, Lean Canvas und SWOT sind optional.
Verifizieren: Die Kanban-Ansicht zeigt die Zahl der Aufgaben je Spalte, das Projekt-Dashboard listet sie unter „Letzte To-Dos“.
Schritt 5: Mailversand per SMTP prüfen
Mit der Mailpit-Konfiguration aus Schritt 1 ging jede Mail sofort in den Testpostfach-Container. Im Test kamen „Sie wurden zu einem neuen Projekt hinzugefügt“ und „Leantime Passwort Rücksetzung“ an.
curl -s http://localhost:8025/api/v1/messages | grep -o '"Subject":"[^"]*"'
Im Betrieb ersetzen Sie die Mailpit-Werte durch Ihren Server, etwa LEAN_EMAIL_SMTP_HOSTS=smtp.example.de, LEAN_EMAIL_SMTP_PORT=587, LEAN_EMAIL_SMTP_SECURE=STARTTLS, LEAN_EMAIL_SMTP_AUTH=true plus Zugangsdaten, und entfernen den Dienst mailpit. Mehr zu Mailpit als Testserver lesen Sie in der Anleitung Mailpit mit Docker Compose einrichten.
Verifizieren: Eine Passwort-Rücksetzung auslösen und spätestens nach einer Minute die Mail im Postfach (oder in Mailpit unter Port 8025) prüfen.
Schritt 6: Reverse Proxy und HTTPS
Leantime spricht nur HTTP. Binden Sie den Port hinter einem Reverse Proxy nur lokal, also "127.0.0.1:${LEAN_PORT:-8080}:8080" in der compose.yaml. Ein minimales Beispiel für Caddy:
pm.example.de {
reverse_proxy 127.0.0.1:8080
}
Sobald HTTPS steht, setzen Sie LEAN_SESSION_SECURE=true und starten mit docker compose up -d neu. Leantime setzt das Sitzungscookie dann mit dem Attribut secure. Über reines HTTP verwirft der Browser ein solches Cookie, die Anmeldung landet dann immer wieder auf der Login-Seite. Hintergrund zu Caddy liefert die Anleitung Caddy als Reverse Proxy mit automatischem HTTPS.
Verifizieren: curl -sI https://pm.example.de/auth/login | grep -i set-cookie zeigt bei leantime_session die Attribute secure; httponly.
Schritt 7: Backup erstellen
Zu sichern sind Datenbank und Uploads. mysqldump --single-transaction erzeugt einen konsistenten Stand ohne Stillstand. Im Ordner /opt/leantime heißen die Volumes leantime_userfiles und leantime_public_userfiles. Prüfen Sie das mit docker volume ls.
#!/bin/bash
# /opt/leantime/backup.sh
set -e
cd /opt/leantime
mkdir -p backup
D=$(date +%F)
docker compose exec -T leantime_db sh -c \
'exec mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --single-transaction --routines leantime' \
> backup/leantime-$D.sql
for v in userfiles public_userfiles; do
docker run --rm -v leantime_$v:/data:ro -v "$PWD/backup":/backup alpine \
tar czf /backup/$v-$D.tgz -C /data .
done
ls -la backup
Sichern Sie zusätzlich compose.yaml und .env, denn ohne LEAN_SESSION_PASSWORD und die Datenbank-Zugangsdaten lässt sich der Stand nicht 1:1 zurückholen. Für automatische, verschlüsselte Kopien außer Haus eignet sich Borgmatic, das den Ordner backup mitnimmt.
Verifizieren: grep -c "INSERT INTO" backup/leantime-*.sql ist größer als 0, und tar tzf backup/userfiles-*.tgz listet Ihre Dateien.
Schritt 8: Wiederherstellung nachweisen
Im Test lag vor dem Backup eine Marker-Datei marker.txt mit dem Inhalt MARKER-4711 in userfiles. Danach wurden Datenbank und Volume komplett geleert und aus der Sicherung zurückgeholt. Stoppen Sie Leantime vorher, damit keine offenen Verbindungen den Vorgang stören.
cd /opt/leantime
D=2026-10-09
docker compose stop leantime
docker compose exec -T leantime_db sh -c 'mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e \
"DROP DATABASE leantime; CREATE DATABASE leantime CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT ALL ON leantime.* TO \"lean\"@\"%\";"'
docker compose exec -T leantime_db sh -c 'mysql -u root -p"$MYSQL_ROOT_PASSWORD" leantime' \
< backup/leantime-$D.sql
docker run --rm -v leantime_userfiles:/data -v "$PWD/backup":/backup:ro alpine \
sh -c 'rm -rf /data/* && tar xzf /backup/userfiles-'$D'.tgz -C /data'
docker compose start leantime
Nach dem Start waren Projekt, alle vier Aufgaben inklusive Umlauten und die Marker-Datei zurück, die Anmeldung mit dem alten Passwort funktionierte:
10 Inhalte der Startseite sammeln
11 Designentwurf abstimmen
12 Hosting und Domain klären
13 Sitemap der neuen Website
MARKER-4711

Verifizieren: docker compose exec leantime cat /var/www/html/userfiles/marker.txt gibt den Marker aus, und die Aufgaben erscheinen wieder in der Kanban-Ansicht.
Schritt 9: Updates und Rollback
Patch-Versionen erscheinen oft, zwischen 3.10.1 und 3.10.4 lagen drei Tage. Aktualisieren Sie bewusst per Tag in der .env.
cd /opt/leantime
./backup.sh
sed -i 's/^LEAN_VERSION=.*/LEAN_VERSION=3.10.4/' .env
docker compose pull leantime
docker compose up -d
curl -sI http://localhost:8080 | grep -i location
Im Test lief ein Sprung von 3.9.8 auf 3.10.4. Nach dem Neustart leitete Leantime jede Anfrage auf /install/update um. Die Seite „Datenbank aktualisieren“ fordert ausdrücklich ein Backup und startet die Migration per „Jetzt aktualisieren!“. Die interne Datenbankversion stieg dabei von 3.5.20 auf 3.5.27. Erst danach war die Anmeldung wieder erreichbar. Schließen Sie die Migration nach jedem Update sofort ab.
Rollback: Das alte Image allein genügt nicht, weil die Migration das Schema verändert. Alten Tag eintragen und den Dump von vor dem Update wie in Schritt 8 einspielen.
Verifizieren: curl -s http://localhost:8080/auth/login | grep -o 'leantime-version" content="[^"]*' zeigt die neue Versionsnummer.
Troubleshooting
Leantime leitet plötzlich auf /install um
Das wirkt wie eine verlorene Installation, im Test war die Ursache aber ein falsches LEAN_DB_PASSWORD. Leantime kann die Benutzertabelle nicht lesen und hält sich für nicht installiert. Das Log unter storage/logs zeigt den eigentlichen Fehler:
production.ERROR: SQLSTATE[HY000] [1045] Access denied for user 'lean'@'172.18.0.4' (using password: YES)
Lösung: Passwort in der .env korrigieren, docker compose up -d. Den Installer in diesem Zustand nicht erneut ausführen.
Port bereits belegt
Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint leantime-leantime-1 (...): Bind for 0.0.0.0:8025 failed: port is already allocated
LEAN_PORT in der .env ändern, danach docker compose up -d --force-recreate leantime.
Anmeldung springt immer zurück zur Login-Seite
LEAN_SESSION_SECURE=true bei Zugriff über HTTP. Entweder HTTPS nutzen oder den Wert auf false setzen.
Plugins verschwinden nach Neustart
Das Volume plugins fehlt. Laut Projekt-README werden Plugins ohne dieses Volume beim Neustart entfernt.
Häufige Fragen
Kann ich MariaDB statt MySQL verwenden?
Die Systemanforderungen nennen MySQL 8.0+ oder MariaDB 10.6+. Die offizielle Compose-Datei nutzt MySQL 8.4, diese Kombination wurde hier eingesetzt.
Gibt es LDAP oder Single Sign-on?
Ja, die sample.env enthält Abschnitte für LDAP (OpenLDAP und Active Directory) und OpenID Connect mit Rollenzuordnung. Laut README sind diese Funktionen in der Open-Source-Version enthalten.
Wie halte ich Passwörter aus der .env heraus?
Für LEAN_DB_PASSWORD, LEAN_EMAIL_SMTP_PASSWORD, LEAN_S3_SECRET und LEAN_SESSION_PASSWORD unterstützt das Image Varianten mit _FILE, etwa für Docker Secrets unter /run/secrets.
Leantime entfernen
cd /opt/leantime
./backup.sh
# Container und Netzwerk entfernen, Daten bleiben
docker compose down
# ACHTUNG: löscht Datenbank, Uploads und Plugins endgültig
docker compose down -v
Warnung: docker compose down -v löscht alle Volumes, also Datenbank, Uploads und Plugins, ohne Rückfrage. Führen Sie es nur aus, wenn ein geprüftes Backup existiert oder die Daten wirklich weg sollen.
Fazit
Leantime ist schnell betriebsbereit: zwei Container, eine .env, ein Installer. Die Stärke liegt in der Verbindung von Zielen und Aufgaben für Teams, die keine PM-Spezialisten sind. Stolperstellen: Das Passwort entsteht erst im Assistenten, ein falsches Datenbank-Passwort tarnt sich als Neuinstallation, und Updates verlangen eine Migration im Browser. Mit festgeschriebenem Image-Tag, Dump plus Volume-Archiv und einem einmal geübten Restore ist der Betrieb für kleine Teams gut beherrschbar.
Weiterführende Anleitungen und Quellen
- Planka mit Docker Compose: Kanban-Projektmanagement
- OpenProject auf Synology: Projektmanagement mit Gantt
- Borgmatic mit Docker für automatische Server-Backups
- Offizielles Docker-Repository mit Compose-Datei und Beispielkonfiguration
- Leantime-Projekt auf GitHub mit Funktionsliste und Update-Hinweisen
- Versionshinweise zu Leantime 3.10.4
- Leantime-Image auf Docker Hub mit Versions-Tags


