SCA

OWASP Dependency-Track 5 met PostgreSQL deployen met Docker Compose

Een productierijpe Docker Compose-opzet voor Dependency-Track 5 op uw eigen infrastructuur, van de eerste login tot SBOM-uploads vanuit CI/CD.

Wat Dependency-Track doet

OWASP Dependency-Track houdt de componenten van derden bij in alles wat u levert. Uw buildpipeline uploadt na elke build een software bill of materials (SBOM). Dependency-Track slaat die op, controleert elke component tegen kwetsbaarheidsdatabases zoals de NVD, GitHub Advisories en OSV, en blijft controleren lang nadat de build klaar is. Wordt er een nieuwe kwetsbaarheid gepubliceerd voor een component die u gebruikt, dan krijgt uw team een melding via e-mail, Slack, Microsoft Teams, Mattermost of een webhook.

Dat laatste maakt het meer dan een scanner. Een scan vertelt u wat er kwetsbaar was op de dag van de build. Dependency-Track vertelt u wat er sindsdien kwetsbaar is geworden, voor elk product en elke versie die u nog ondersteunt.

Voor fabrikanten die zich voorbereiden op de EU Cyber Resilience Act is dat direct bruikbaar. De CRA vereist een SBOM die ten minste uw top-level dependencies dekt, monitoring op bekende kwetsbaarheden in componenten van derden en herstel zonder onnodige vertraging gedurende de ondersteuningsperiode. Dependency-Track dekt daarvan het inventaris- en het monitoringdeel. Onze CRA-gids voor het mkb legt de verplichtingen uitgebreider uit.

Wat er veranderd is in Dependency-Track 5

Dependency-Track 5 is sinds juni 2026 algemeen beschikbaar. Draaide u versie 4, dan zijn dit de wijzigingen die de deployment raken:

  • v5 draait alleen op PostgreSQL. Ondersteuning voor H2, MySQL en Microsoft SQL Server is verdwenen, inclusief de ingebouwde H2-database die v4 makkelijk uit te proberen maakte.
  • Images komen nu uit de registry van GitHub, ghcr.io/dependencytrack/. Het gebundelde image met één container en het WAR-bestand worden niet meer gepubliceerd.
  • De database-instellingen zijn verhuisd van ALPINE_DATABASE_* naar DT_DATASOURCE_*.
  • Health checks en Prometheus-metrics hebben hun eigen poort, 9000, los van de REST API op poort 8080.
  • Meerdere instanties van de API-server kunnen één database delen en coördineren via PostgreSQL. Eén instantie volstaat voor de meeste kleine en middelgrote teams.

Dependency-Track 4.14 krijgt beveiligingsupdates tot 9 december 2026. Plan uw upgrade vóór die datum; de migratiegids van het project beschrijft hoe u uw gegevens overzet.

Wat u nodig hebt

  • Een Linux-host met Docker Engine en de Docker Compose-plugin. Zie Install Docker Engine.
  • Voor de API-server: ten minste 2 GB geheugen en bij voorkeur 4 CPU-cores. Onder 1 GB houdt hij echte belasting niet bij.
  • Voor PostgreSQL: het project raadt 8 GB geheugen en 4 cores aan op een aparte host met SSD- of NVMe-opslag, en zelfs voor een evaluatie niet minder dan 4 GB en 2 cores. Op dezelfde host draaien is prima om mee te beginnen; verhuis de database naar een eigen host of naar een beheerde PostgreSQL-dienst als uw portfolio groeit.
  • Twee hostnamen als u het buiten localhost beschikbaar maakt, bijvoorbeeld dtrack.example.com voor de frontend en dtrack-api.example.com voor de API-server.

Het Docker Compose-bestand

Het bestand hieronder draait drie services: PostgreSQL, de API-server en de frontend. Vergeleken met het quick-start-bestand van het project leest het het databasewachtwoord uit een Docker secret, pint het de imageversies vast en begrenst het de resources van de API-server.

Download compose.yaml

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: {}

Een paar keuzes in dit bestand zijn bewust:

  • De database heeft geen gepubliceerde poort. Alleen de API-server praat met PostgreSQL, via het interne Compose-netwerk. Poort 5432 publiceren of een webbeheertool zoals Adminer toevoegen, vergroot alleen het aanvalsoppervlak.
  • Alle poorten zijn gebonden aan 127.0.0.1, dus niets is vanaf het netwerk bereikbaar tot u er een reverse proxy voor zet.
  • Het databasewachtwoord staat in een bestand. PostgreSQL leest het via POSTGRES_PASSWORD_FILE, Dependency-Track via de verwijzing ${file::...}. De dubbele $$ voorkomt dat Compose het als een van zijn eigen variabelen behandelt.
  • De imageversies zijn vastgepind. Met latest kan de volgende docker compose pull Dependency-Track of PostgreSQL upgraden zonder dat iemand daartoe besluit. Kijk op de releasepagina voor de nieuwste 5.x-patch en lees de upgradenotities voordat u de tag aanpast.
  • De frontend serveert alleen statische bestanden, dus API_BASE_URL moet het adres zijn waarmee de browsers van uw gebruikers de API-server bereiken, niet een interne containernaam.

Starten

Maak het wachtwoordbestand aan, zonder afsluitende nieuwe regel, en start de 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

Bij de eerste start worden het databaseschema en de standaardteams aangemaakt, wat een minuut duurt. Controleer of de API-server klaar is:

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

Open daarna http://localhost:8081 en log in met admin / admin. Dependency-Track vraagt u direct een nieuw wachtwoord in te stellen.

Lokale accounts zijn prima voor een evaluatie. Voor productie raadt het project aan OpenID Connect of LDAP/Active Directory te koppelen, zodat mensen inloggen met hun bedrijfsaccount.

Achter TLS zetten

Beëindig TLS op een reverse proxy en laat de containers op gewoon HTTP draaien. De proxy moet de headers X-Forwarded-Proto en X-Forwarded-For doorgeven, zodat auditlogs en links in meldingen de publieke URL tonen. Met Caddy, dat certificaten en die headers voor u regelt, is de configuratie vier regels per host:

dtrack.example.com {
	reverse_proxy 127.0.0.1:8081
}

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

Zet daarna API_BASE_URL: https://dtrack-api.example.com in het Compose-bestand en voer docker compose up -d opnieuw uit. Nginx, Traefik of uw bestaande load balancer werken op dezelfde manier.

De kwetsbaarheidsbronnen inschakelen

Ga naar Administration › Vulnerability Sources en schakel de bronnen in die u wilt:

  • De NVD heeft geen inloggegevens nodig. De eerste spiegeling downloadt de hele dataset en duurt even.
  • GitHub Advisories heeft een personal access token of een GitHub App nodig. Het is de moeite waard, omdat de advisories vaak eerder verschijnen en preciezer aan packagenamen te koppelen zijn dan NVD-vermeldingen.
  • OSV heeft geen inloggegevens nodig. Schakel de ecosystemen in die u echt gebruikt.

Sinds versie 5.1 spiegelt Dependency-Track standaard ook de catalogi van CISA en ENISA met bekende uitgebuite kwetsbaarheden. U kunt die status gebruiken in policies en meldingsfilters, zodat een uitgebuite kwetsbaarheid niet verdrinkt in een lijst met theoretische.

Een project aanmaken en een SBOM uploaden

Een project in Dependency-Track staat voor één product, library of dienst, meestal met één versie per release die u ondersteunt. Maak er een aan via Projects › Create Project en upload een CycloneDX-SBOM op het tabblad Components van het project om het resultaat te zien.

Eerst hebt u een CycloneDX-SBOM nodig. De meeste build-ecosystemen hebben een generator: de CycloneDX-plugins voor Maven en Gradle, cdxgen voor veel talen of Syft voor container-images. Het CycloneDX Tool Center noemt ze allemaal. Dependency-Track 5.1 accepteert CycloneDX tot en met versie 1.7.

Handmatig uploaden is prima om het uit te proberen. In de praktijk hoort uw pipeline het na elke build te doen.

SBOM’s uploaden vanuit uw CI/CD-pipeline

Uw pipeline heeft een API-sleutel nodig met de permissie BOM_UPLOAD. Het standaardteam Automation heeft die, samen met PROJECT_CREATION_UPLOAD, waarmee een upload het project kan aanmaken als het nog niet bestaat. Genereer een sleutel voor dat team via Administration › Access Management › Teams, of maak per pipeline een apart team aan zodat u sleutels één voor één kunt intrekken.

Bewaar de sleutel als secret in uw CI-systeem. Zet hem nooit in het pipelinebestand of de repository.

Upload daarna de SBOM na elke build:

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]"

Met autoCreate=true maakt Dependency-Track het project en de versie aan bij de eerste upload. Beheert u projecten liever met de hand, laat het dan weg en identificeer het project via de UUID, met -F "project=<uuid>". U vindt de UUID onder View Details van het project.

Upload één versie per release die u ondersteunt, niet alleen de main-branch. Komt er een nieuwe kwetsbaarheid uit, dan wilt u weten welke geleverde versies erdoor geraakt worden, want die draaien uw klanten en die verwacht de CRA dat u herstelt.

Back-ups en upgrades

Alle persistente gegevens staan in PostgreSQL, dus een databaseback-up is een volledige back-up:

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

Plan dit in, kopieer de dumps naar een andere locatie en test minstens één keer een restore. Wilt u de database bekijken, gebruik dan docker compose exec postgres psql -U dtrack dtrack in plaats van een webbeheertool open te zetten.

Lees voor een upgrade de upgradenotities van de release, maak een back-up, pas de imagetags in compose.yaml aan en voer uit:

docker compose pull
docker compose up -d

Volgende stappen

Zodra de SBOM’s binnenkomen, zit de waarde in wat u met de bevindingen doet. Stel meldingen in voor nieuwe kritieke en bekende uitgebuite kwetsbaarheden, maak componentpolicies voor licenties en verouderde componenten, en spreek af wie per product de bevindingen triageert. De documentatie van Dependency-Track behandelt elk van deze punten.

Wilt u hulp bij het inpassen van Dependency-Track in uw veilige ontwikkelcyclus of uw voorbereiding op de CRA? Plan een gratis gesprek.