Dependency-Track on AWS User Guide
Overview
This image runs Dependency-Track, the OWASP software supply-chain component-analysis platform. Dependency-Track ingests CycloneDX Software Bills of Materials (SBOMs) for your applications and maintains a living inventory of every component they depend on, continuously identifying known vulnerabilities, outdated libraries and policy violations as new intelligence arrives. Instead of a point-in-time scan, it keeps a durable, queryable picture of software supply-chain risk across every project in your portfolio.
The platform runs as a Java API server (on OpenJDK 25, which Dependency-Track 5.x requires) fronted by nginx as a reverse proxy. The single-page web application is served on port 80, and the API is reached through the same origin under /api. A PostgreSQL database holds the component inventory, findings and configuration. The API server's main port (8080) and its management/metrics port (9000) are kept off the public interface: the management endpoint binds loopback only, and an nftables ruleset drops any external traffic to both ports, so nginx on port 80 is the only intended public listener. The PostgreSQL data directory and the API server data directory both live on a dedicated EBS data volume mounted at /var/lib/dependency-track, independently resizable and separate from the operating system disk.
On the first boot of every deployed instance, a one-shot service rotates the well-known default admin account to a fresh per-instance password through the Dependency-Track API, rotates the PostgreSQL role password, verifies the new credential works and that the default admin/admin no longer authenticates, and writes the login to /root/dependency-track-credentials.txt with mode 0600. No shared or default credentials ship in the image.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and inbound ports 80 and 443 from the networks your developers and build agents will reach Dependency-Track on
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Dependency-Track. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. The API server JVM (around a 4 GiB heap), its analysis workers and a local PostgreSQL share the instance, and vulnerability-database mirroring is memory and IO hungry, so m5.large is the floor for this stack. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your users use. Leave the root volume at the default size or larger; the image adds a separate data volume for the database and API server storage automatically.
Select Launch instance. First boot initialisation runs before SSH becomes ready; on m5.large the platform is serving within a couple of minutes of the instance reaching Running with its status checks passed.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Dependency-Track Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 80, and 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=dependency-track-01}]'
The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Step 3: Connect and Retrieve the Administrator Login
Connect over SSH with the key pair you selected and the public IP address from step 2. The SSH login user depends on the operating system of the AMI variant you launched:
| AMI variant | SSH login user |
|---|---|
| Dependency-Track 5.0 on Ubuntu 24.04 | ubuntu |
The first boot service runs before the SSH daemon becomes ready, so the credentials file is always in place when you log in for the first time.
ssh <login-user>@<public-ip>
sudo cat /root/dependency-track-credentials.txt
You will see a plain text file containing the sign-in URL, the administrator username (admin) and the per-instance password. From the same SSH session you can confirm the deployment is healthy — the health endpoint is open and served by nginx, and the API reports its version through the same nginx proxy:
curl -s http://127.0.0.1/health
curl -s http://127.0.0.1/api/version
The health endpoint returns ok and the version endpoint returns a JSON document whose version field is the running Dependency-Track release.
Step 4: First Sign-In to the Web UI
Open http://<public-ip>/ in your browser. You are presented with the Dependency-Track sign-in screen. Sign in with the username admin and the per-instance password from /root/dependency-track-credentials.txt. The default admin/admin credential has already been rotated away on first boot and no longer works.

After signing in you land on the portfolio dashboard, which summarises portfolio vulnerabilities, projects at risk, vulnerable components and the inherited risk score across everything you have analysed. It is empty on a fresh instance until you upload your first SBOM.

Step 5: Upload Your First SBOM
Dependency-Track builds its inventory from CycloneDX SBOMs. You can upload one through the web UI (Projects → Create Project, then the project's Components → Upload BOM) or through the API. The block below authenticates with the per-instance admin password, generates a session token, and uploads a small CycloneDX SBOM through the API, auto-creating a project called my-first-app. Run it on the instance over SSH.
PW=$(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=$PW")
cat > /tmp/my-first-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
B64=$(base64 -w0 < /tmp/my-first-bom.json)
jq -nc --arg b "$B64" '{projectName:"my-first-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 @-
The response contains a processing token. Dependency-Track processes the upload asynchronously; the next block waits for processing to finish, then confirms the project and its analysed components exist.
PW=$(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=$PW")
UUID=$(curl -s -H "Authorization: Bearer $TOKEN" \
--get --data-urlencode "name=my-first-app" --data-urlencode "version=1.0.0" \
http://127.0.0.1/api/v1/project/lookup | jq -r '.uuid')
echo "project uuid: $UUID"
curl -s -H "Authorization: Bearer $TOKEN" \
"http://127.0.0.1/api/v1/component/project/$UUID?limit=100" | jq 'length'
The project lookup returns a UUID and the component count is the number of components in the SBOM. In the web UI the same project now appears under Projects, showing its version, the CycloneDX BOM format, its risk score and vulnerability count.

Opening a project and selecting the Components tab shows the full dependency inventory built from the SBOM, each component with its version, group, licence and risk score, and the buttons to upload a new BOM or download the current one.

Step 6: Enable Vulnerability Sources
A fresh instance has an empty vulnerability database. To have Dependency-Track match your components against known vulnerabilities, enable and mirror the vulnerability sources under Administration → Vulnerability Sources (for example the National Vulnerability Database, the GitHub Advisory Database and OSS Index). Once a source is enabled and its initial mirror completes, Dependency-Track re-analyses your existing projects automatically and populates the vulnerability counts on the dashboard and project views. The Administration area is also where you configure BOM formats, analyzers, repositories, notifications, integrations and access management.

Step 7: Integrate SBOM Upload into Your Pipeline
The same PUT /api/v1/bom call you ran in step 5 is how you wire SBOM analysis into CI/CD. Generate a CycloneDX SBOM during your build (for example with the CycloneDX Maven, Gradle or npm plugins), then upload it against a project keyed by name and version so every release is analysed automatically. For pipeline use, create a dedicated team with an API key under Administration → Access Management and send it as the X-Api-Key header instead of an interactive session token, so your automation never uses the interactive admin password.
Step 8: Add HTTPS with a Trusted Certificate
The image serves plain HTTP on port 80 so it works immediately on launch. For any real deployment, put Dependency-Track behind HTTPS. Point a DNS record at the instance, ensure inbound port 443 is open, then install a certificate with certbot and the nginx plugin. Replace your-domain with your fully qualified hostname.
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain
certbot obtains a certificate, rewrites the nginx server block to listen on 443, and sets up automatic renewal. After enabling HTTPS, set the Base URL under Administration → Configuration → General to your https:// URL so generated links and notifications use it.
Step 9: Services, Storage and Maintenance
The stack runs under systemd. Check and control the services with:
systemctl status dependency-track postgresql nginx
dependency-track.service is the API server, postgresql.service is the database, and nginx.service is the reverse proxy. The API server and management ports are kept off the public interface by the nftables.service ruleset; you can inspect it with sudo nft list table inet cloudimg_dtrack.
The database and the API server data directory (vulnerability mirrors, local file storage and the secret-management key set) live on the dedicated EBS data volume mounted at /var/lib/dependency-track. Confirm the mount and its free space with:
df -h /var/lib/dependency-track
Because the data tier is a separate EBS volume you can grow it independently of the operating system disk, and snapshot it for backup. For a consistent database backup, run pg_dump of the dtrack database as the postgres user, or snapshot the EBS volume. Keep the operating system patched with sudo apt-get update && sudo apt-get upgrade.
Support
This image is maintained by cloudimg with 24/7 technical support by email and chat. We can help with deployment, SBOM ingestion, vulnerability-source configuration, policy design, CI/CD integration, database and storage maintenance, backup and upgrade planning. Contact support@cloudimg.co.uk.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.