Dependency-Track on Ubuntu 24.04 on Azure User Guide
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, and Dependency-Track keeps an always-current inventory of every component in that software, continuously re-evaluating 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 — which is why it is used to run software supply chain risk programmes across large portfolios.
The cloudimg image installs the official Dependency-Track 5.0.2 API server distribution and the official frontend single-page application, both 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, with nginx 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 — 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 that password is rotated to a unique per-VM value, the rotation is verified, and the default credential is confirmed rejected before the VM is handed over. The result is written to /root/dependency-track-credentials.txt with mode 0600, so no two VMs ever share credentials and the shipped default is never usable. Backed by 24/7 cloudimg support.
What is included:
- Dependency-Track 5.0.2 API server (
/opt/dependency-track) on the OpenJDK 25 JRE, run as the non-rootdtrackuser - The official Dependency-Track frontend SPA served by nginx on
:80, with/apireverse-proxied to the API server and an unauthenticated/healthendpoint - PostgreSQL 16 as the backing database, bound to loopback only
- A dedicated 40 GiB Azure data disk at
/var/lib/dependency-trackholding 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
8080and the management port9000off the public interface, so nginx on:80is the only way in - Telemetry submission disabled by default
- JVM heap sized automatically at first boot from the VM's actual memory
- Per-VM
adminpassword, rotated at first boot, in a root-only file dependency-track.service,postgresql.service,nginx.serviceandnftables.serviceas systemd units, enabled and active- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B4ms (4 vCPU / 16 GiB RAM) is the recommended starting point — the API server JVM, its analysis workers and PostgreSQL share the VM, and vulnerability database mirroring is memory and IO hungry. NSG inbound: allow 22/tcp from your management network and 80/tcp from the networks your users and CI runners will reach Dependency-Track on (front port 80 with TLS for public exposure — 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 cloudimg, and select Create. On Basics 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 Review + create → Create.
First boot initialisation takes approximately three to five minutes after the VM starts — Dependency-Track runs its database migrations, seeds its default objects and rotates the admin password on first boot.
Step 2 — Deploy from the Azure CLI
az vm create \
--resource-group my-resource-group \
--name my-dependency-track \
--image cloudimg: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 shipped admin / admin default is rotated and then verified to be 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, 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 confirm the same credential over the API, and confirm the shipped default is dead:
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
Dependency-Track is driven by SBOMs. 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 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. This inventory is what every future advisory is evaluated against.

Step 9 — Review vulnerabilities
Vulnerabilities shows the vulnerability intelligence Dependency-Track has mirrored, and Vulnerability Audit is where findings against your own projects are triaged. Mirroring the full National Vulnerability Database on a new instance runs in the background and takes a while to complete on first boot; findings against your projects populate as it does.

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, so they are independently resizable and separate from the OS disk.
sudo nft list table inet cloudimg_dtrack
The ruleset keeps ports 8080 and 9000 off the public interface — 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 exposing 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/cloudimg-dependency-track to listen on :443 with your certificate and redirects :80 to :443. Renewal is handled by the packaged systemd timer. Once TLS is in place, restrict 80/tcp and 443/tcp in the NSG to the networks that need access.
Backup and maintenance
The backing database is the thing to back up — 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 (Azure Blob Storage, or an Azure Backup policy on the data disk). Because both the database and the API server data directory live on /var/lib/dependency-track, a disk snapshot of that data disk captures the full application state.
Operating system security updates are delivered by Ubuntu's unattended-upgrades, which is enabled in the image. 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
This image is published and supported by cloudimg. For help with deployment or configuration, contact support@cloudimg.co.uk. Product documentation for Dependency-Track is at docs.dependencytrack.org.