Gitleaks mit Docker installieren: Schneller Secret-Scanner für Git-Repositories
Hardcodierte API-Keys, Passwörter und Tokens im Git-Repository? Gitleaks findet sie per Regex und Entropie-Analyse — als schlankes 24-MB-Docker-Image, das in jede CI/CD-Pipeline passt und ohne Datenbank auskommt.

Einmal „git push" und schon liegt der AWS-Key öffentlich im Repository — ein Szenario, das laut Studien tausendfach täglich passiert. Gitleaks ist ein quelloffenes SAST-Werkzeug (Static Application Security Testing), das Git-Historien, Branches und Verzeichnisse per konfigurierbaren Regex-Regeln und Entropie-Analyse nach Secrets durchsucht: API-Keys, Passwörter, private Schlüssel, OAuth-Tokens. Mit über 27.000 GitHub-Stars und mehr als zehn Millionen Docker-Pulls ist es das meistgenutzte Tool seiner Art im Container-Ökosystem. Diese Anleitung richtet Gitleaks plattformneutral über Docker Compose ein — auf einem Linux-Host, einer VM oder einem NAS mit Docker — und zeigt, wie du einzelne Repositories on-demand scannst, Reports erzeugst und den Scanner in CI/CD-Workflows einbindest.
Voraussetzungen
- Docker Engine 20.10+ und Docker Compose Plugin v2 (
docker compose, nicht das altedocker-compose) — falls noch nicht installiert: Docker und Docker Compose auf Linux installieren. - Linux-Host, VM, NAS oder WSL2 — Gitleaks-Images sind Multi-Arch (amd64, arm64, armv6/7).
- Ein lokal ausgechecktes Git-Repository mit vollständiger History (
.git-Verzeichnis muss im Mount-Root liegen). - Ausgabeverzeichnis
./reports/auf dem Host anlegen (einmalig, sonst schlägt der Report-Write fehl). - Keine Datenbank, kein API-Key, kein offener Port erforderlich — Gitleaks ist vollständig zustandslos.
Schritt 1: Eckdaten und Projektordner
Bevor du die Konfigurationsdateien anlegst, ein Blick auf die wichtigsten Parameter:
| Parameter | Wert |
|---|---|
| Image (empfohlen) | ghcr.io/gitleaks/gitleaks:latest |
| Alternatives Image | zricethezav/gitleaks:latest (Docker Hub) |
| Aktueller stabiler Tag | v8.30.1 (Stand März 2026) |
| Image-Größe | ca. 23,9 MB (Alpine/Distroless) |
| Exponierter Port | keiner — CLI-Tool, kein Daemon |
| Datenbank | keine |
| Report-Formate | JSON, CSV, JUnit, SARIF, Go-Template |
| Exit-Code bei Leaks | 1 (überschreibbar mit --exit-code=0) |
| Exit-Code kein Fund | 0 |
Lege den Projektordner und das Report-Verzeichnis an:
mkdir -p ~/gitleaks/reports
cd ~/gitleaksVerifizieren: ls -la ~/gitleaks/ zeigt das Verzeichnis reports/. Ohne dieses Verzeichnis schlägt der Report-Write im Container mit einem Permission-Fehler fehl.
Schritt 2: .env-Datei anlegen
Alle variablen Pfade und Einstellungen kommen in eine .env-Datei — so musst du die compose.yaml nie anfassen, wenn du ein anderes Repository scannst.
# Pfad zum zu scannenden Git-Repository (muss .git-Verzeichnis enthalten)
REPO_PATH=/home/user/mein-projekt
# Ausgabeverzeichnis für Reports (muss auf dem Host existieren)
REPORT_PATH=./reports
# Pfad zur optionalen Konfigurationsdatei (eigene Regeln, Allowlists)
# Datei muss existieren, wenn der Mount aktiv ist!
# Auskommentieren, wenn du nur die Default-Regeln nutzen willst.
CONFIG_PATH=./.gitleaks.toml
# Report-Format: json | csv | junit | sarif | template
REPORT_FORMAT=jsonPasse REPO_PATH auf das Verzeichnis an, in dem dein .git-Ordner liegt — also den Repository-Root, nicht ein Unterverzeichnis.
Verifizieren: cat ~/gitleaks/.env zeigt die gesetzten Variablen. Prüfe, ob REPO_PATH auf ein Verzeichnis zeigt, das tatsächlich ein .git-Unterverzeichnis enthält (ls /home/user/mein-projekt/.git).
Schritt 3: compose.yaml anlegen
Gitleaks ist kein Daemon, sondern ein CLI-Tool. Deshalb verwendet die Compose-Datei restart: "no" und den Profile-Mechanismus — du startest den Scan bewusst per docker compose run, kein automatischer Neustart in einer Endlosschleife.
services:
gitleaks:
image: ghcr.io/gitleaks/gitleaks:latest
container_name: gitleaks-scanner
restart: "no"
volumes:
- ${REPO_PATH:-./repo}:/repo:ro
- ${REPORT_PATH:-./reports}:/reports
- ${CONFIG_PATH:-./.gitleaks.toml}:/gitleaks.toml:ro
environment:
- GITLEAKS_CONFIG=/gitleaks.toml
command: >
git
--source=/repo
--report-format=${REPORT_FORMAT:-json}
--report-path=/reports/gitleaks-report.${REPORT_FORMAT:-json}
--verbose
--exit-code=0
profiles:
- scanHinweise zur Konfiguration:
gitstattdetect: Der Unterbefehldetectist seit v8.19.0 deprecated und wurde durchgit(für Repositories) unddir(für Verzeichnisse ohne Git-Kontext) ersetzt. Ältere Anleitungen im Web verwenden noch die alten Befehle — sie funktionieren noch, sind aber nicht mehr empfohlen.:robeim Repo-Mount: Das Repository wird read-only eingebunden — Gitleaks schreibt nie ins Quell-Repo.--exit-code=0: Standardmäßig gibt Gitleaks Code 1 zurück, wenn Findings vorhanden sind, was CI/CD-Pipelines abbricht. Für Audit-only-Betrieb ist Code 0 sinnvoll; in der Pipeline kannst du dies anpassen.- CONFIG_PATH ohne eigene Datei: Wenn du keine eigene
.gitleaks.tomlanlegen möchtest, entferne den dritten Volume-Eintrag sowie dieGITLEAKS_CONFIG-Umgebungsvariable. Dann greift die Default-Konfiguration.
Verifizieren: docker compose config im Projektordner gibt die aufgelöste Konfiguration fehlerfrei aus. Zeigt Docker eine Warnung zu fehlenden Variablen, prüfe, ob die .env-Datei im selben Verzeichnis wie compose.yaml liegt.
Schritt 4: Optionale Gitleaks-Konfigurationsdatei anlegen
Wenn du CONFIG_PATH=./.gitleaks.toml gesetzt hast, muss die Datei existieren, bevor du den Container startest — sonst bricht der Start mit einem Konfigurationsfehler ab. Eine minimale .gitleaks.toml als Ausgangspunkt:
# .gitleaks.toml — Minimalkonfiguration
title = "Mein Gitleaks Config"
[extend]
# Standardregeln von Gitleaks einbinden
useDefault = true
# Beispiel: Bekanntes False-Positive-Muster ignorieren
[[allowlist.regexes]]
description = "Lokaler Testschlüssel"
regex = '''test_secret_[a-z0-9]{8}'''Du kannst diese Datei auf das Minimum [extend]\nuseDefault = true reduzieren — das reicht für den Einstieg. Eigene Regeln fügst du als [[rules]]-Blöcke hinzu.
Verifizieren: ls -la ~/gitleaks/.gitleaks.toml zeigt die Datei. Fehlt sie, und GITLEAKS_CONFIG ist gesetzt, bricht der Container beim Start mit einem Fehler ab.
Schritt 5: Ersten Scan ausführen
Da der Service unter einem Profile läuft, startest du ihn mit docker compose run statt mit docker compose up:
docker compose run --rm gitleaksGitleaks lädt das Image (beim ersten Start), scannt das Repository und schreibt den Report nach ./reports/gitleaks-report.json. Eine typische Ausgabe sieht so aus:
○
│╲
│ ○
○ ░
░ gitleaks
Finding: ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Secret: ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
RuleID: github-pat
Entropy: 3.58
File: config/settings.py
Line: 42
Commit: a1b2c3d4...
Author: Max Mustermann
Fingerprint: config/settings.py:github-pat:42
5:30PM INF scan completed in 4.2s
5:30PM WRN leaks found: 3Verifizieren:
docker compose logs gitleakszeigt die Scan-Zusammenfassung.ls -lh ~/gitleaks/reports/zeigt die Report-Datei — eine fehlende Datei deutet auf ein Volume-Mount-Problem hin.cat ~/gitleaks/reports/gitleaks-report.json | head -50zeigt die ersten Findings im JSON-Format.
Schritt 6: Report auswerten und Findings verwalten
Der JSON-Report enthält für jeden Fund Dateiname, Zeilennummer, Commit-Hash, Autor, Datum und einen eindeutigen Fingerprint. Drei Wege, mit Findings umzugehen:
Option A: Inline-Ausnahme im Code
Wenn ein Secret bewusst gesetzt ist (z. B. ein Testtoken in einer Unit-Test-Datei), füge den Kommentar direkt hinter die betroffene Zeile ein:
TEST_API_KEY = "test_secret_abc12345" #gitleaks:allowOption B: .gitleaksignore-Datei
Für bereits bekannte Findings in der Git-History — die du nicht mehr rückgängig machen kannst — trägst du den Fingerprint in eine .gitleaksignore-Datei ein:
# .gitleaksignore — bekannte, akzeptierte Findings
config/settings.py:github-pat:42Diese Datei legst du im Repository-Root ab — Gitleaks findet sie automatisch — oder bindest sie per Volume-Mount ein.
Option C: Baseline-Workflow
Für Legacy-Repositories mit vielen historischen Findings ist der Baseline-Ansatz ideal: erst einen vollständigen Scan als Baseline speichern, dann beim nächsten Lauf nur neue Findings melden:
# Baseline erstellen
docker compose run --rm gitleaks git \
--source=/repo \
--report-format=json \
--report-path=/reports/baseline.json \
--exit-code=0
# Nur neue Findings (ab jetzt) melden
docker compose run --rm gitleaks git \
--source=/repo \
--baseline-path=/reports/baseline.json \
--report-format=json \
--report-path=/reports/new-findings.jsonVerifizieren: Nach dem Baseline-Lauf zeigt ls -lh ~/gitleaks/reports/ beide Dateien. Im zweiten Lauf meldet die Ausgabe „0 leaks found", wenn keine neuen Secrets hinzugekommen sind.
Schritt 7: Image aktualisieren
Gitleaks veröffentlicht regelmäßig Security-Patches. Ein Update ist mit zwei Befehlen erledigt — mehr zum Thema Container-Updates findest du in der Anleitung Docker-Container automatisch aktualisieren nach dem Watchtower-Aus.
docker compose pull
docker compose run --rm gitleaks --versionVerifizieren: Die --version-Ausgabe zeigt die neue Versionsnummer, z. B. gitleaks version 8.30.1.
Bonus: CI/CD-Integration
Gitleaks ist besonders wertvoll als automatischer Pipeline-Schritt, der jeden Push prüft, bevor Code in den Hauptbranch gelangt. Auch hier gilt das Prinzip „Docker Compose absichern" — Secrets gehören nicht in Konfigurationsdateien, sondern in einen dedizierten Secrets-Manager.
GitHub Actions
name: Secret Scan
on: [push, pull_request]
jobs:
gitleaks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # vollständige History, kein Shallow Clone!
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}GitLab CI
gitleaks:
image: ghcr.io/gitleaks/gitleaks:latest
variables:
GIT_DEPTH: 0 # vollständige History
script:
- gitleaks git --source=. --exit-code=1
artifacts:
reports:
sast: gitleaks-report.json
when: alwaysWichtig in beiden Fällen: vollständige Git-History auschecken (fetch-depth: 0 bzw. GIT_DEPTH: 0), sonst scannt Gitleaks nur den letzten Commit und übersieht ältere eingecheckte Secrets.
Troubleshooting / Typische Fehler
- „fatal: not a git repository": Der Volume-Mount zeigt nicht auf den Repository-Root. Fix:
REPO_PATHin der.envauf das Verzeichnis setzen, das.git/direkt enthält, z. B./home/user/mein-projektstatt/home/user/mein-projekt/src. - „dubious ownership": Seit Git 2.35.2 verweigert Git Operationen in Repos, die einem anderen UID gehören. Fix: Repository mit
:romounten (bereits in der compose.yaml gesetzt) oder im Container-Befehlgit config --global --add safe.directory /repovoranstellen. - 0 Commits gescannt trotz vorhandener History: Das Repository wurde als Shallow Clone ausgecheckt. Fix: In GitHub Actions
fetch-depth: 0setzen; in GitLab CIGIT_DEPTH: 0. - Container startet und startet neu…:
restart: alwaysstattrestart: "no"in dercompose.yaml— Gitleaks ist kein Daemon. Fix:restart: "no"undprofiles: [scan]wie in dieser Anleitung verwenden. - Report-Datei fehlt nach dem Scan: Das
./reports/-Verzeichnis auf dem Host existiert nicht. Fix:mkdir -p ~/gitleaks/reportsausführen, dann erneut scannen. - „Error loading config file":
GITLEAKS_CONFIG=/gitleaks.tomlist gesetzt, aber die Datei fehlt oder der Volume-Mount ist falsch. Fix:.gitleaks.tomlanlegen oderGITLEAKS_CONFIG-Variable und den entsprechenden Mount aus dercompose.yamlentfernen. - Pipeline bricht bei Findings ab: Gitleaks gibt standardmäßig Exit-Code 1 zurück. Für rein informativen Betrieb:
--exit-code=0imcommand-Abschnitt setzen und den Report separat auswerten. - Langer Scan oder OOM bei großer History: Fix:
--max-target-megabytesund--timeoutFlags nutzen oder den Scan-Bereich mit--log-opts 'HEAD~50..HEAD'einschränken.
Häufige Fragen
Brauche ich eine Datenbank oder weitere Container?
Nein. Gitleaks ist vollständig zustandslos und läuft als einzelner Container ohne jegliche externe Abhängigkeit. Kein Redis, kein PostgreSQL, keine Sidecar-Container — das macht es zum idealen Baustein in schlanken CI/CD-Pipelines.
Wie starte ich den Scan nach der Einrichtung?
Mit docker compose run --rm gitleaks (da der Service unter einem Profile läuft). Das --rm-Flag entfernt den Container nach dem Scan automatisch. Der Container beendet sich nach Abschluss von selbst.
Kann ich nur bestimmte Commits oder Branches scannen?
Ja, mit dem --log-opts-Flag. Beispiele: --log-opts='main..feature-branch' scannt nur die Commits im Feature-Branch; --log-opts='HEAD~10..HEAD' die letzten zehn Commits. Das Flag kannst du direkt im command-Abschnitt der compose.yaml ergänzen.
Welches Report-Format eignet sich am besten für CI/CD?
SARIF für GitHub Code Scanning (direktes Upload in den Security-Tab, Findings erscheinen im PR); JUnit für Jenkins und GitLab Testreports (Findings als fehlgeschlagene Tests); JSON für eigene Weiterverarbeitung oder SIEM-Integration.
Wie ignoriere ich bekannte False-Positives dauerhaft?
Zwei Wege: Den Fingerprint des Findings in eine .gitleaksignore-Datei im Repository-Root eintragen — Gitleaks findet sie automatisch. Oder den Inline-Kommentar #gitleaks:allow direkt hinter die betroffene Code-Zeile schreiben, was die Ausnahme transparent im Code dokumentiert.
Ist Gitleaks noch aktiv gepflegt?
Das Projekt gilt laut Maintainer Zach Rice als „feature complete" — neue Features werden nicht mehr gemergt, nur noch Sicherheits-Patches. Die bestehende Funktionalität ist stabil und produktionsreif. Für neue Features wird auf den Nachfolger Betterleaks verwiesen. Für den produktiven Einsatz als Secret-Scanner ist Gitleaks v8.x vollständig ausreichend.
Was ist der Unterschied zwischen git und dir als Unterbefehl?
git scannt ein vollständiges Git-Repository inklusive der gesamten Commit-History — das ist der Standardfall. dir (Alias: files, directory) scannt ein beliebiges Verzeichnis ohne Git-Kontext, also nur den aktuellen Dateizustand ohne History. Letzteren nutzt du z. B. zum Scannen von Konfigurationsverzeichnissen, die kein Git-Repository sind.
Fazit
Gitleaks ist das schärfste Werkzeug, wenn du schnell und unkompliziert eingecheckte Secrets aufspüren willst. Das schlanke 24-MB-Image, die Zustandslosigkeit und die breite CI/CD-Unterstützung machen es zum Standardbaustein in jedem DevSecOps-Workflow. Die Einrichtung dauert keine 15 Minuten; danach hast du sowohl On-Demand-Scans als auch eine automatische Pipeline-Absicherung. Wichtig: Das Projekt ist feature-complete, bekommt aber weiterhin Security-Patches — für Produktivsysteme ist das kein Problem, wer neue Features benötigt, schaut sich Betterleaks an.
Wer seinen Docker-Stack grundsätzlich härten möchte, findet praktische Tipps in Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only und Docker-Images auf Schwachstellen scannen mit Trivy. Den nächsten logischen Schritt — Secrets zentral und sicher verwalten statt in Konfigurationsdateien ablegen — deckt Infisical mit Docker: Open-Source Secrets Management ab.
Weiterführende Anleitungen und Quellen
- Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only für den Produktivbetrieb
- Docker-Images auf Schwachstellen scannen mit Trivy: CVE-Check, SBOM und automatische Scans
- Infisical mit Docker: Open-Source Secrets Management
- Docker und Docker Compose auf Linux installieren: die Self-Hosting-Grundlage
- VPS absichern und härten: UFW, SSH-Keys und Fail2Ban
Offizielle Quellen: Gitleaks GitHub README · Gitleaks GitHub Releases · Gitleaks Docker Hub