SCA

OWASP Dependency-Track 5 mit PostgreSQL per Docker Compose betreiben

Ein produktionsreifes Docker-Compose-Setup für Dependency-Track 5 auf eigener Infrastruktur, vom ersten Login bis zum SBOM-Upload aus Ihrer CI/CD-Pipeline.

Was Dependency-Track leistet

OWASP Dependency-Track behält die Drittkomponenten in allem im Blick, was Sie ausliefern. Ihre Build-Pipeline lädt nach jedem Build eine Software Bill of Materials (SBOM) hoch. Dependency-Track speichert sie, prüft jede Komponente gegen Schwachstellendatenbanken wie die NVD, GitHub Advisories und OSV und prüft weiter, lange nachdem der Build abgeschlossen ist. Wird für eine Komponente, die Sie nutzen, eine neue Schwachstelle veröffentlicht, erhält Ihr Team eine Benachrichtigung per E-Mail, Slack, Microsoft Teams, Mattermost oder Webhook.

Genau das macht es zu mehr als einem Scanner. Ein Scan sagt Ihnen, was am Tag des Builds verwundbar war. Dependency-Track sagt Ihnen, was seitdem verwundbar geworden ist, für jedes Produkt und jede Version, die Sie noch unterstützen.

Für Hersteller, die sich auf den EU Cyber Resilience Act vorbereiten, ist das direkt nützlich. Der CRA verlangt eine SBOM, die mindestens die Abhängigkeiten der obersten Ebene abdeckt, die Überwachung bekannter Schwachstellen in Drittkomponenten und Korrekturen ohne Verzögerung während des Unterstützungszeitraums. Dependency-Track deckt davon die Bestandsaufnahme und die Überwachung ab. Unser CRA-Leitfaden für KMU erklärt die Pflichten ausführlicher.

Was sich mit Dependency-Track 5 geändert hat

Dependency-Track 5 ist seit Juni 2026 allgemein verfügbar. Wenn Sie Version 4 betrieben haben, betreffen diese Änderungen die Bereitstellung:

  • v5 läuft nur noch mit PostgreSQL. Die Unterstützung für H2, MySQL und Microsoft SQL Server entfällt, auch die eingebettete H2-Datenbank, mit der sich v4 leicht ausprobieren ließ.
  • Die Images kommen jetzt aus der Registry von GitHub, ghcr.io/dependencytrack/. Das gebündelte Ein-Container-Image und die WAR-Datei werden nicht mehr veröffentlicht.
  • Die Datenbankeinstellungen heißen nicht mehr ALPINE_DATABASE_*, sondern DT_DATASOURCE_*.
  • Health Checks und Prometheus-Metriken haben einen eigenen Port, 9000, getrennt von der REST-API auf Port 8080.
  • Mehrere API-Server-Instanzen können sich eine Datenbank teilen und über PostgreSQL koordinieren. Für die meisten kleinen und mittleren Teams reicht eine Instanz.

Dependency-Track 4.14 erhält Sicherheitsupdates bis zum 9. Dezember 2026. Planen Sie Ihr Upgrade vorher; der Migrationsleitfaden des Projekts beschreibt die Übernahme Ihrer Daten.

Was Sie brauchen

  • Einen Linux-Host mit Docker Engine und dem Docker-Compose-Plugin. Siehe Install Docker Engine.
  • Für den API-Server: mindestens 2 GB Arbeitsspeicher und idealerweise 4 CPU-Kerne. Unter 1 GB hält er realer Last nicht stand.
  • Für PostgreSQL: Das Projekt empfiehlt 8 GB Arbeitsspeicher und 4 Kerne auf einem eigenen Host mit SSD- oder NVMe-Speicher, und selbst zur Evaluierung nicht weniger als 4 GB und 2 Kerne. Für den Anfang ist derselbe Host in Ordnung; lagern Sie die Datenbank aus oder wechseln Sie zu einem verwalteten PostgreSQL-Dienst, wenn Ihr Portfolio wächst.
  • Zwei Hostnamen, wenn Sie das System über localhost hinaus erreichbar machen, zum Beispiel dtrack.example.com für das Frontend und dtrack-api.example.com für den API-Server.

Die Docker-Compose-Datei

Die Datei unten betreibt drei Dienste: PostgreSQL, den API-Server und das Frontend. Im Vergleich zur Quick-Start-Datei des Projekts liest sie das Datenbankpasswort aus einem Docker Secret, pinnt die Image-Versionen und begrenzt die Ressourcen des API-Servers.

compose.yaml herunterladen

name: dependency-track

services:
  postgres:
    image: postgres:18-alpine
    environment:
      POSTGRES_DB: dtrack
      POSTGRES_USER: dtrack
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 5s
      timeout: 3s
      retries: 5
    volumes:
      - postgres-data:/var/lib/postgresql
    restart: unless-stopped

  apiserver:
    image: ghcr.io/dependencytrack/apiserver:5.1.0
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DT_DATASOURCE_URL: jdbc:postgresql://postgres:5432/dtrack
      DT_DATASOURCE_USERNAME: dtrack
      DT_DATASOURCE_PASSWORD: "$${file::/run/secrets/db_password}"
    secrets:
      - db_password
    deploy:
      resources:
        limits:
          memory: 2g
          cpus: "4"
    ports:
      - "127.0.0.1:8080:8080" # REST API
      - "127.0.0.1:9000:9000" # health checks and metrics
    volumes:
      - apiserver-data:/data
    restart: unless-stopped

  frontend:
    image: ghcr.io/dependencytrack/frontend:5.1.0
    environment:
      API_BASE_URL: http://localhost:8080
    ports:
      - "127.0.0.1:8081:8080"
    restart: unless-stopped

secrets:
  db_password:
    file: ./secrets/db_password.txt

volumes:
  apiserver-data: {}
  postgres-data: {}

Einige Entscheidungen in dieser Datei sind bewusst getroffen:

  • Die Datenbank hat keinen veröffentlichten Port. Nur der API-Server spricht mit PostgreSQL, über das interne Compose-Netzwerk. Port 5432 zu veröffentlichen oder ein Web-Admin-Tool wie Adminer hinzuzufügen, vergrößert nur die Angriffsfläche.
  • Alle Ports sind an 127.0.0.1 gebunden, sodass nichts aus dem Netzwerk erreichbar ist, bis Sie einen Reverse Proxy davorsetzen.
  • Das Datenbankpasswort liegt in einer Datei. PostgreSQL liest es über POSTGRES_PASSWORD_FILE, Dependency-Track über die Referenz ${file::...}. Das doppelte $$ verhindert, dass Compose es als eigene Variable behandelt.
  • Die Image-Versionen sind gepinnt. Mit latest könnte das nächste docker compose pull Dependency-Track oder PostgreSQL aktualisieren, ohne dass jemand das entschieden hat. Auf der Release-Seite finden Sie den neuesten 5.x-Patch; lesen Sie die Upgrade-Hinweise, bevor Sie den Tag ändern.
  • Das Frontend liefert nur statische Dateien aus. API_BASE_URL muss daher die Adresse sein, über die die Browser Ihrer Nutzer den API-Server erreichen, kein interner Containername.

Starten

Legen Sie die Passwortdatei ohne abschließenden Zeilenumbruch an und starten Sie den Stack:

mkdir -p secrets
printf '%s' "$(openssl rand -base64 32)" > secrets/db_password.txt
chmod 600 secrets/db_password.txt

docker compose up -d
docker compose logs -f apiserver

Beim ersten Start werden das Datenbankschema und die Standardteams angelegt, das dauert etwa eine Minute. Prüfen Sie, ob der API-Server bereit ist:

curl -s http://localhost:9000/health/ready

Öffnen Sie dann http://localhost:8081 und melden Sie sich mit admin / admin an. Dependency-Track fordert Sie sofort auf, ein neues Passwort zu setzen.

Lokale Konten reichen für die Evaluierung. Für den Produktivbetrieb empfiehlt das Projekt, OpenID Connect oder LDAP/Active Directory anzubinden, damit sich die Nutzer mit ihrem Firmenkonto anmelden.

Hinter TLS stellen

Terminieren Sie TLS an einem Reverse Proxy und lassen Sie die Container auf einfachem HTTP. Der Proxy muss die Header X-Forwarded-Proto und X-Forwarded-For weitergeben, damit Audit-Logs und Links in Benachrichtigungen die öffentliche URL zeigen. Mit Caddy, das Zertifikate und diese Header für Sie erledigt, besteht die Konfiguration aus vier Zeilen pro Host:

dtrack.example.com {
	reverse_proxy 127.0.0.1:8081
}

dtrack-api.example.com {
	reverse_proxy 127.0.0.1:8080
}

Setzen Sie danach API_BASE_URL: https://dtrack-api.example.com in der Compose-Datei und führen Sie docker compose up -d erneut aus. Nginx, Traefik oder Ihr vorhandener Load Balancer funktionieren genauso.

Die Schwachstellenquellen aktivieren

Gehen Sie zu Administration › Vulnerability Sources und aktivieren Sie die gewünschten Quellen:

  • Die NVD braucht keine Zugangsdaten. Die erste Spiegelung lädt den gesamten Datensatz herunter und dauert eine Weile.
  • GitHub Advisories braucht ein Personal Access Token oder eine GitHub App. Die Einrichtung lohnt sich, weil die Advisories oft früher erscheinen und sich genauer Paketnamen zuordnen lassen als NVD-Einträge.
  • OSV braucht keine Zugangsdaten. Aktivieren Sie die Ökosysteme, die Sie tatsächlich nutzen.

Seit Version 5.1 spiegelt Dependency-Track standardmäßig auch die Kataloge bekannter ausgenutzter Schwachstellen von CISA und ENISA. Diesen Status können Sie in Policies und Benachrichtigungsfiltern nutzen, damit eine ausgenutzte Schwachstelle nicht in einer Liste theoretischer untergeht.

Ein Projekt anlegen und eine SBOM hochladen

Ein Projekt in Dependency-Track steht für ein Produkt, eine Bibliothek oder einen Dienst, meist mit einer Version pro unterstütztem Release. Legen Sie es unter Projects › Create Project an und laden Sie auf dem Reiter Components des Projekts eine CycloneDX-SBOM hoch, um das Ergebnis zu sehen.

Zuerst brauchen Sie eine CycloneDX-SBOM. Die meisten Build-Ökosysteme haben einen Generator: die CycloneDX-Plugins für Maven und Gradle, cdxgen für viele Sprachen oder Syft für Container-Images. Das CycloneDX Tool Center listet sie alle auf. Dependency-Track 5.1 akzeptiert CycloneDX bis Version 1.7.

Zum Ausprobieren genügt der Upload von Hand. In der Praxis sollte Ihre Pipeline das nach jedem Build erledigen.

SBOMs aus Ihrer CI/CD-Pipeline hochladen

Ihre Pipeline braucht einen API-Schlüssel mit der Berechtigung BOM_UPLOAD. Das Standardteam Automation hat sie, zusammen mit PROJECT_CREATION_UPLOAD, womit ein Upload das Projekt anlegen kann, falls es noch nicht existiert. Erzeugen Sie unter Administration › Access Management › Teams einen Schlüssel für dieses Team, oder legen Sie pro Pipeline ein eigenes Team an, damit Sie Schlüssel einzeln widerrufen können.

Speichern Sie den Schlüssel als Secret in Ihrem CI-System. Legen Sie ihn nie in der Pipeline-Datei oder im Repository ab.

Laden Sie dann nach jedem Build die SBOM hoch:

curl -sSf -X POST "https://dtrack-api.example.com/api/v1/bom" \
  -H "X-Api-Key: ${DT_API_KEY}" \
  -F "autoCreate=true" \
  -F "projectName=my-product" \
  -F "projectVersion=${VERSION}" \
  -F "[email protected]"

Mit autoCreate=true legt Dependency-Track Projekt und Version beim ersten Upload an. Wenn Sie Projekte lieber von Hand verwalten, lassen Sie es weg und identifizieren Sie das Projekt stattdessen über seine UUID, mit -F "project=<uuid>". Die UUID finden Sie unter View Details des Projekts.

Laden Sie eine Version pro unterstütztem Release hoch, nicht nur den Main-Branch. Wenn eine neue Schwachstelle erscheint, wollen Sie wissen, welche ausgelieferten Versionen betroffen sind, denn diese betreiben Ihre Kunden, und diese sollen Sie laut CRA beheben.

Sichern und aktualisieren

Alle persistenten Daten liegen in PostgreSQL, ein Datenbank-Backup ist also ein vollständiges Backup:

docker compose exec -T postgres pg_dump -U dtrack -Fc dtrack > dtrack-$(date +%F).dump

Planen Sie das regelmäßig ein, kopieren Sie die Dumps auf ein anderes System und testen Sie mindestens einmal eine Wiederherstellung. Wenn Sie die Datenbank einsehen müssen, nutzen Sie docker compose exec postgres psql -U dtrack dtrack, statt ein Web-Admin-Tool freizugeben.

Für ein Upgrade lesen Sie die Upgrade-Hinweise des Releases, erstellen ein Backup, ändern die Image-Tags in compose.yaml und führen aus:

docker compose pull
docker compose up -d

Nächste Schritte

Sobald SBOMs eingehen, entsteht der Nutzen aus dem, was Sie mit den Befunden tun. Richten Sie Benachrichtigungen für neue kritische und bekannte ausgenutzte Schwachstellen ein, legen Sie Komponenten-Policies für Lizenzen und veraltete Komponenten an und vereinbaren Sie, wer die Befunde für jedes Produkt triagiert. Die Dokumentation von Dependency-Track behandelt jeden dieser Punkte.

Wenn Sie Unterstützung dabei möchten, Dependency-Track in Ihren sicheren Entwicklungszyklus oder Ihre CRA-Vorbereitung einzubinden, buchen Sie ein kostenloses Gespräch.