Deployment guide

Dependency-Track

Overview

Dependency-Track is the OWASP flagship platform for software supply chain component analysis. You upload a CycloneDX SBOM (Software Bill of Materials) for each project you ship. Dependency-Track keeps an always-current inventory of every component in that software and continuously re-evaluates it against vulnerability intelligence as new advisories are published.

Rather than telling you what was vulnerable the day you scanned, it tells you what is vulnerable now. This is why teams use it to run software supply chain risk programmes across large portfolios.

The SecureAnyCloud image installs the official Dependency-Track 5.0.2 API server distribution and the official frontend single-page application. Both are verified against the upstream release SHA256 checksums at build time. The API server runs under a dedicated non-root dtrack service user on the OpenJDK 25 JRE. nginx sits in front as the only public listener: it serves the frontend on port 80 and reverse-proxies /api to the API server.

A local PostgreSQL is the backing store, because Dependency-Track 5.x requires PostgreSQL and no longer supports an embedded database.

Dependency-Track seeds a well-known default admin / admin account. On the first boot of every deployed VM, the image rotates that password to a unique per-VM value, verifies the rotation, and confirms the default credential is rejected before the VM is handed over. The result is written to /root/dependency-track-credentials.txt with mode 0600, so no two VMs share credentials and the shipped default is never usable.

What you get:

  • Dependency-Track 5.0.2 API server (/opt/dependency-track) on the OpenJDK 25 JRE, run as the non-root dtrack user
  • The official Dependency-Track frontend SPA served by nginx on :80, with /api reverse-proxied to the API server and an unauthenticated /health endpoint
  • PostgreSQL 16 as the backing database, bound to loopback only
  • A dedicated 40 GiB Azure data disk at /var/lib/dependency-track holding the API server data directory and the PostgreSQL datadir, separate from the OS disk and re-provisioned with every VM
  • An nftables ruleset keeping the API server port 8080 and the management port 9000 off the public interface, so nginx on :80 is the only way in
  • Telemetry submission disabled by default
  • JVM heap sized automatically at first boot from the VM's actual memory
  • Per-VM admin password, rotated at first boot, in a root-only file
  • dependency-track.service, postgresql.service, nginx.service and nftables.service as systemd units, enabled and active
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B4ms (4 vCPU / 16 GiB RAM) is the recommended starting size. The API server JVM, its analysis workers and PostgreSQL share the VM, and vulnerability database mirroring is memory- and IO-hungry.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp from the networks your users and CI runners reach Dependency-Track on. For public exposure, front port 80 with TLS (see Enabling HTTPS).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Dependency-Track by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).

Review the dedicated data disk on the Disks tab, then select Review + create and Create.

First boot initialisation takes approximately three to five minutes after the VM starts. During this time Dependency-Track runs its database migrations, seeds its default objects and rotates the admin password.

Step 2 - Deploy from the Azure CLI

az vm image terms accept --urn sac1647283583153:dependency-track-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-resource-group \
  --name my-dependency-track \
  --image sac1647283583153:dependency-track-ubuntu-24-04:default:latest \
  --size Standard_B4ms \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
az vm open-port --resource-group my-resource-group --name my-dependency-track --port 80

Step 3 - Connect to your VM

ssh azureuser@<vm-ip>

Step 4 - Confirm the services are running

systemctl is-active dependency-track.service postgresql.service nginx.service nftables.service curl -s -o /dev/null -w 'health: HTTP %{http_code}\n' http://127.0.0.1/health curl -s http://127.0.0.1/api/version

All four units report active, the health endpoint returns 200, and the version endpoint reports Dependency-Track 5.0.2.

Step 5 - Retrieve your administrator login

Every VM generates its own administrator password at first boot. The image rotates the shipped admin / admin default and then verifies that it is rejected, so it can never be used against your instance.

sudo cat /root/dependency-track-credentials.txt
sudo stat -c '%n mode=%a owner=%U:%G' /root/dependency-track-credentials.txt

The file is mode 600, is owned by root, and holds DTRACK_USERNAME and DTRACK_ADMIN_PASSWORD for this VM only.

Step 6 - First sign-in

Browse to http://<vm-ip>/ and sign in as admin with the password from Step 5.

You can also confirm the same credential over the API, and confirm that the shipped default is rejected:

PASS=$(sudo grep '^DTRACK_ADMIN_PASSWORD=' /root/dependency-track-credentials.txt | cut -d= -f2-)
TOKEN=$(curl -s -X POST http://127.0.0.1/api/v1/user/login \
  --data-urlencode "username=admin" --data-urlencode "password=$PASS")
curl -s -o /dev/null -w 'authenticated API call: HTTP %{http_code}\n' \
  -H "Authorization: Bearer $TOKEN" http://127.0.0.1/api/v1/team
curl -s -o /dev/null -w 'default admin/admin: HTTP %{http_code} (401 expected)\n' \
  -X POST http://127.0.0.1/api/v1/user/login \
  --data-urlencode "username=admin" --data-urlencode "password=admin"

Step 7 - Upload your first SBOM

SBOMs drive Dependency-Track. Generate a CycloneDX SBOM for your project with a tool such as cyclonedx-npm, cyclonedx-maven-plugin or syft, then upload it.

The example below creates a small SBOM and uploads it, so you can see the whole path working end to end.

cat > /tmp/example-bom.json <<'BOM' { "bomFormat": "CycloneDX", "specVersion": "1.5", "version": 1, "components": [ {"type":"library","group":"org.apache.logging.log4j","name":"log4j-core","version":"2.14.1","purl":"pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1"}, {"type":"library","name":"lodash","version":"4.17.15","purl":"pkg:npm/lodash@4.17.15"} ] } BOM
PASS=$(sudo grep '^DTRACK_ADMIN_PASSWORD=' /root/dependency-track-credentials.txt | cut -d= -f2-)
TOKEN=$(curl -s -X POST http://127.0.0.1/api/v1/user/login \
  --data-urlencode "username=admin" --data-urlencode "password=$PASS")
UPLOAD_TOKEN=$(jq -nc --arg b "$(base64 -w0 < /tmp/example-bom.json)" \
  '{projectName:"example-app", projectVersion:"1.0.0", autoCreate:true, bom:$b}' \
  | curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -X PUT http://127.0.0.1/api/v1/bom --data-binary @- | jq -r .token)
echo "upload token: $UPLOAD_TOKEN"

Processing is asynchronous. Poll until it completes, then confirm that the components were analysed:

PASS=$(sudo grep '^DTRACK_ADMIN_PASSWORD=' /root/dependency-track-credentials.txt | cut -d= -f2-)
TOKEN=$(curl -s -X POST http://127.0.0.1/api/v1/user/login \
  --data-urlencode "username=admin" --data-urlencode "password=$PASS")
PROJECT_UUID=$(curl -s -H "Authorization: Bearer $TOKEN" \
  --get --data-urlencode "name=example-app" --data-urlencode "version=1.0.0" \
  http://127.0.0.1/api/v1/project/lookup | jq -r .uuid)
curl -s -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1/api/v1/component/project/$PROJECT_UUID?limit=20" \
  | jq -r '.[] | "\(.name) \(.version) \(.purl)"'

In the web interface the uploaded project appears under Projects, with its BOM format and last import time.

Step 8 - Review the analysed components

Open a project and choose Components to see every component Dependency-Track extracted from the SBOM, each with its Package URL. Dependency-Track evaluates every future advisory against this inventory.

Step 9 - Review vulnerabilities

Vulnerabilities shows the vulnerability intelligence Dependency-Track has mirrored. Vulnerability Audit is where you triage findings against your own projects.

Mirroring the full National Vulnerability Database on a new instance runs in the background and takes a while to complete after first boot. Findings against your projects populate as the mirror progresses.

Step 10 - Confirm the data tiers

findmnt -no SOURCE,TARGET,FSTYPE /var/lib/dependency-track
sudo -u postgres psql -tAc 'SHOW data_directory' grep '^DT_DATA_DIRECTORY=' /etc/dependency-track/dependency-track.env

Both the PostgreSQL datadir and the API server data directory sit on the dedicated Azure data disk. You can resize the disk independently, and it is separate from the OS disk.

sudo nft list table inet sac_dtrack

The ruleset keeps ports 8080 and 9000 off the public interface, so nginx on :80 is the only way in.

Enabling HTTPS

Dependency-Track handles SBOMs and vulnerability data for your software estate, so terminate TLS before you expose it beyond a trusted network.

Point a DNS record at the VM, then use certbot to obtain a certificate and update the nginx site:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d dependency-track.your-domain.com --redirect --agree-tos -m you@your-domain.com

Certbot rewrites /etc/nginx/sites-available/sac-dependency-track to listen on :443 with your certificate and redirects :80 to :443. The packaged systemd timer handles renewal.

Once TLS is in place, restrict 80/tcp and 443/tcp in the NSG to the networks that need access.

Backup and maintenance

Back up the backing database. It holds every project, SBOM inventory, finding and audit decision:

sudo -u postgres pg_dump -Fc dtrack > /var/tmp/dtrack-$(date +%F).dump ls -lh /var/tmp/dtrack-*.dump

Copy the dump off the VM, for example to Azure Blob Storage, or apply an Azure Backup policy to the data disk. Both the database and the API server data directory live on /var/lib/dependency-track, so a snapshot of that data disk captures the full application state.

Ubuntu's unattended-upgrades, which is enabled in the image, delivers operating system security updates. To upgrade Dependency-Track itself, follow the upstream release notes. The API server is a self-contained distribution in /opt, and the frontend is a static bundle served by nginx.

Support

SecureAnyCloud publishes and supports this image. For help with deployment or configuration, contact sales@secureanycloud.com. Product documentation for Dependency-Track is at docs.dependencytrack.org.

Deploy on Azure

Launch Dependency-Track on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure