DefectDojo
Overview
DefectDojo is the OWASP application vulnerability management platform. This DevSecOps tool consolidates the findings from your SAST, DAST, SCA, container and infrastructure scanners into a single system of record. It de-duplicates and tracks findings across products, engagements and tests, and it drives remediation through a configurable workflow. It supports JIRA and notification integrations and exposes a complete REST API, so it can sit at the centre of an automated security pipeline.
The SecureAnyCloud image installs DefectDojo 3.0.100 as the official django-DefectDojo Docker Compose stack and runs it as a systemd service. A working vulnerability-management platform is online within minutes of launch.
What you get:
- DefectDojo 3.0.100 (BSD-3-Clause) deployed from the official
django-DefectDojoDocker Compose stack, pinned to the 3.0.100 published images, so the image never silently upgrades at build time - Docker Engine (Docker CE) and the Docker Compose plugin, installed from the official Docker package repository
- The DefectDojo Compose stack: the
nginxreverse proxy on port 80, theuwsgiDjango application server, theceleryworkerandcelerybeatasync task services, the one-shotinitializer(runs the database migrations and creates the admin account),postgres(PostgreSQL 18, the primary database) andvalkey(Valkey 9, the Celery broker and cache) - All stateful data (the PostgreSQL database, the Valkey data and the DefectDojo media and uploads) on a dedicated 40 GiB data disk mounted at
/var/lib/defectdojo. Docker's data-root is relocated there, and the disk is independently resizable and re-provisioned on every VM - A per-VM
adminaccount with a generated password, created at first boot - Two systemd units:
defectdojo.service(a oneshot wrapper arounddocker compose up -d) anddefectdojo-firstboot.service - 24/7 SecureAnyCloud support
Prerequisites
- An active Azure subscription, an SSH key, and a VNet with a subnet
- A VM size of Standard_B4ms (4 vCPU / 16 GB RAM), which is the recommended size and is comfortable for the DefectDojo stack
- Network security group inbound rules that allow
22/tcpfrom your management CIDR for SSH and80/tcpfrom the CIDR that needs the DefectDojo web UI and API. Add443/tcpif you enable HTTPS
Connect over SSH
Replace <vm-ip> with the public IP address of your VM. The default login user is azureuser.
ssh azureuser@<vm-ip>Confirm the services are active
sudo systemctl is-active docker.service defectdojo.service docker --version docker compose versionThe output shows active twice, followed by the Docker Engine version and the Docker Compose v2 plugin version.
Confirm the DefectDojo containers are running
cd /opt/defectdojo && sudo docker compose -f docker-compose.yml -f docker-compose.override.sac.yml --env-file .env psThe core services (nginx, uwsgi, celeryworker, celerybeat, postgres and valkey) show the Up / running state. The one-shot initializer shows Exited (0) after it completes the migrations and creates the admin account.
Confirm the data disk is mounted
All stateful DefectDojo data lives on a dedicated data disk mounted at /var/lib/defectdojo. Check the mount:
findmnt /var/lib/defectdojo df -h /var/lib/defectdojofindmnt shows the device backing /var/lib/defectdojo and df confirms the 40 GiB volume.
Check the DefectDojo login page
The bundled nginx reverse proxy serves the DefectDojo login page without authentication on port 80. It returns HTTP 200.
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/loginA 200 confirms the web UI is up.
Read the per-VM admin credentials
A unique admin password is generated for your instance on its first boot and written to a root-only file.
sudo cat /root/defectdojo-credentials.txtThe file lists defectdojo.url (where to sign in), defectdojo.admin.user (admin) and defectdojo.admin.pass. Store the password securely.
Sign in to the DefectDojo web UI
Browse to http://<vm-ip>/ and sign in with the username admin and the defectdojo.admin.pass from Step 6. The bundled nginx reverse proxy serves both the UI and the API on port 80.
After you sign in, the DefectDojo dashboard opens. It summarises your products, engagements and current findings posture.
Organise your work into products and engagements
DefectDojo models your work as products (the application or system under test), engagements (a period of testing against a product) and tests (the individual scans whose results you import). Create a product, create an engagement within it, and then import a scan report to populate findings.
Triage findings
The Findings view consolidates every imported vulnerability across your products and engagements, de-duplicated and ranked by severity. From here you can triage findings, accept risk, mark findings as mitigated or false-positive, and drive remediation.
Use the REST API
DefectDojo exposes a complete REST API under /api/v2/. Obtain an API token with your admin credentials, and then call any endpoint with the Authorization: Token <token> header.
curl -s -X POST http://<vm-ip>/api/v2/api-token-auth/ \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"<password from Step 6>"}'The response contains a token field. Use the token to import scan results, query findings and integrate DefectDojo into your CI/CD pipeline.
Manage the stack
The defectdojo.service systemd unit manages the whole stack. It wraps docker compose under /opt/defectdojo.
sudo systemctl restart defectdojo.service
sudo systemctl status defectdojo.service --no-pagerTo inspect logs for a specific service:
cd /opt/defectdojo && sudo docker compose -f docker-compose.yml -f docker-compose.override.sac.yml --env-file .env logs --tail 50 uwsgiEnabling HTTPS on your own domain
The image serves plain HTTP on port 80 out of the box. To serve DefectDojo over HTTPS on your own domain, terminate TLS in front of the VM. For example, use an Azure Application Gateway or a reverse proxy with a Let's Encrypt certificate, pointing at the VM on port 80.
Set DD_ALLOWED_HOSTS to your domain in /opt/defectdojo/.env before you restart defectdojo.service. Add 443/tcp to your NSG inbound rules.
First-boot security model
On the first boot of each VM, defectdojo-firstboot.service runs once and:
- Rotates every per-VM secret in the stack: the Django secret key (
DD_SECRET_KEY), the AES-256 credential encryption key (DD_CREDENTIAL_AES_256_KEY) and the PostgreSQL password - Generates a fresh, strong
adminpassword and initialises the stack on an empty database, so theinitializercreates the admin account with that password - Verifies the admin API-token round-trip and writes the credentials to
/root/defectdojo-credentials.txt(root-only, mode 0600)
No shared or default secret and no pre-existing login ship in the image.
Support
24/7 technical support is included. Contact SecureAnyCloud at sales@secureanycloud.com for help with deployment, scanner imports and parsers, products and engagements, the findings and de-duplication model, the REST API, JIRA and notification integrations, TLS and backups.
DefectDojo and OWASP are trademarks of the OWASP Foundation. PostgreSQL is a trademark of the PostgreSQL Community Association of Canada. Valkey is a trademark of the Linux Foundation. Docker is a trademark of Docker, Inc. All other 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.
Deploy on Azure
Launch DefectDojo 3.0.100 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
Overview
DefectDojo is an open-source, OWASP flagship DevSecOps and application vulnerability management platform. It consolidates the output of hundreds of security scanners, de-duplicates and triages findings, tracks remediation across products and engagements, and reports on your security posture over time.
The SecureAnyCloud image runs the official DefectDojo production Docker Compose stack (DefectDojo 3.0.100, BSD-3-Clause) behind nginx on port 80, with the database, cache and uploads on a dedicated data volume. A strong administrator password and every application secret are generated uniquely on the first boot of each instance, so no shared or default credential ships in the image.
What you get:
- DefectDojo 3.0.100 as the official Docker Compose stack: nginx, the uwsgi Django app, celery worker and beat, PostgreSQL and Valkey (Redis-compatible)
- The whole stack managed by a single
defectdojo.servicesystemd unit, enabled and active on every boot - All stateful Docker volumes (database, cache, media and uploads) relocated onto a dedicated EBS data volume mounted at
/var/lib/defectdojo - A first-boot service that generates a fresh Django secret key, credential encryption key, database password and a strong per-instance admin password, and records the admin credentials in a root-only file
- An unauthenticated login page that doubles as a health endpoint, and a full REST API for automation
- 24/7 SecureAnyCloud support
Prerequisites
- An AWS account, an EC2 key pair in the target region, and a VPC with a public subnet
- An instance type of m5.large (2 vCPU / 8 GiB RAM), which is recommended. DefectDojo runs several containers, so 8 GiB RAM or more is advised
- Security group inbound rules that allow
22/tcpfrom your management network and80/tcp(and443/tcpif you terminate TLS) for the web console
DefectDojo serves plain HTTP on port 80. For production, terminate TLS in front of it with your own domain so that the console runs over HTTPS.
Step 1 - Launch the AMI
Subscribe to the listing in AWS Marketplace, choose Continue to Launch, and and launch through the EC2 console or the AWS CLI. Select the m5.large instance type, your key pair and a security group that opens ports 22 and 80 (and 443 for TLS).
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <your-key-pair> \
--security-group-ids <security-group-id> \
--subnet-id <subnet-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=defectdojo}]'Step 2 - Connect to your instance
Connect over SSH as the default login user for the OS variant you launched. This listing may ship more than one OS variant, so use the matching login user below.
OS variant SSH login user Connect
Ubuntu 24.04 LTS ubuntu ssh ubuntu@<instance-public-ip>
Step 3 - Confirm the stack is running
DefectDojo runs as a Docker Compose stack wrapped by a single systemd unit. A one-shot first-boot service rotates every secret on the first boot. Confirm that all three are healthy:
systemctl is-active docker.service defectdojo.service defectdojo-firstboot.serviceAll three report active. The defectdojo-firstboot.service unit is a one-shot that remains active after it completes.
Step 4 - Inspect the Compose stack
List the containers that make up the DefectDojo appliance:
sudo docker compose -f /opt/defectdojo/docker-compose.yml -f /opt/defectdojo/docker-compose.override.sac.yml --env-file /opt/defectdojo/.env ps --format 'table {{.Service}}\t{{.Status}}'The containers nginx, uwsgi, celerybeat, celeryworker, postgres and valkey are all Up. nginx publishes the console on host port 80.
Step 5 - Confirm the version and endpoints
Check the running DefectDojo version and that the web endpoints answer:
sudo docker compose -f /opt/defectdojo/docker-compose.yml -f /opt/defectdojo/docker-compose.override.sac.yml --env-file /opt/defectdojo/.env exec -T uwsgi grep -m1 __version__ dojo/__init__.py curl -s -o /dev/null -w 'login page: HTTP %{http_code}\n' http://127.0.0.1/login curl -s -o /dev/null -w 'REST API: HTTP %{http_code}\n' http://127.0.0.1/api/v2/The version reads __version__ = "3.0.100" and the login page returns 200. The login page is unauthenticated, so it works as a load-balancer health check.
Step 6 - The data volume
The database, cache and uploads live on a dedicated EBS data volume mounted at /var/lib/defectdojo, separate from the OS disk. The Docker data-root is relocated there:
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/defectdojoThe output reports an ext4 filesystem mounted at /var/lib/defectdojo. Back up that volume, for example with an EBS snapshot, to preserve your database and uploads.
Step 7 - Retrieve the per-instance admin credentials
The first-boot service generated a unique administrator password for this instance and wrote it to a root-only credentials file. The other rotated secrets are not written to that file. Read the URL and username (the password is on the defectdojo.admin.pass= line):
sudo stat -c '%a %U:%G %n' /root/defectdojo-credentials.txt
sudo grep -E '^defectdojo\.(url|admin\.user)=' /root/defectdojo-credentials.txtThe file is 600 root:root. To display the generated password, run sudo grep '^defectdojo.admin.pass=' /root/defectdojo-credentials.txt.
Step 8 - Prove the admin credential end to end
Confirm that the generated administrator credential authenticates against the REST API and returns a token. A wrong password is rejected:
PASS="$(sudo grep '^defectdojo.admin.pass=' /root/defectdojo-credentials.txt | cut -d= -f2-)" curl -s -o /dev/null -w 'valid password: HTTP %{http_code}\n' -X POST http://127.0.0.1/api/v2/api-token-auth/ -H 'Content-Type: application/json' -d "{\"username\":\"admin\",\"password\":\"$PASS\"}" curl -s -o /dev/null -w 'wrong password: HTTP %{http_code}\n' -X POST http://127.0.0.1/api/v2/api-token-auth/ -H 'Content-Type: application/json' -d '{"username":"admin","password":"wrong-pass-xyz"}'The valid password returns 200 with a token in the body, and the wrong password returns 400.
Step 9 - Sign in to the console
Browse to http://<instance-public-ip>/ in any modern browser. In production, use your own HTTPS domain instead. Sign in as admin with the password from Step 7.
Step 10 - The dashboard
After you sign in, the dashboard opens. It shows KPI tiles for active engagements and recent findings, plus the historical finding severity breakdown and reported severity by month. On a fresh instance these start empty and populate as you import findings.
Step 11 - Import scanner findings
DefectDojo organises work into products, engagements and tests, and understands the output of a very wide range of scanners. You can import from the UI (Engagements -> Import Scan Results) or through the REST API.
The example below creates a product and an engagement on the fly and imports a Generic Findings Import file using the API token:
TOKEN=$(curl -s -X POST http://<instance-public-ip>/api/v2/api-token-auth/ \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"<password from Step 7>"}' | jq -r .token)
curl -s -X POST http://<instance-public-ip>/api/v2/import-scan/ \
-H "Authorization: Token $TOKEN" \
-F 'scan_type=Generic Findings Import' \
-F 'product_name=Acme Storefront' \
-F 'engagement_name=Q3 2026 Application Assessment' \
-F 'auto_create_context=true' \
-F 'active=true' -F 'verified=true' \
-F 'file=@findings.json;type=application/json'Step 12 - Triage findings
Imported findings appear under Findings, de-duplicated and tagged with severity, CWE, SLA age and the tool that reported them. Sort and filter to triage. You can accept risk, assign owners, mark findings as mitigated, or bulk-update them.
Step 13 - Track a product
Each product has an overview page with a severity metrics breakdown, its SLA configuration, and tabs for engagements, findings, components and endpoints. You can see the security posture of one application at a glance.
Maintenance
- Data: The PostgreSQL database, Valkey cache and all uploads live under
/var/lib/defectdojoon the dedicated data volume. Back it up with an EBS snapshot to preserve your findings and history. - Stack control: The whole appliance is one systemd unit. Use
sudo systemctl restart defectdojo.serviceto bounce it, or the underlyingsudo docker compose -f /opt/defectdojo/docker-compose.yml -f /opt/defectdojo/docker-compose.override.sac.yml --env-file /opt/defectdojo/.env <command>for finer control. - Credentials: The per-instance admin password is in
/root/defectdojo-credentials.txt. After your first sign-in, change it in the DefectDojo UI (Profile -> Change Password) for day-to-day use. - TLS: DefectDojo serves plain HTTP on port 80. In production, front it with TLS and your own domain so that the console runs over HTTPS.
DD_ALLOWED_HOSTSis set to*, so any hostname is accepted out of the box. - Upgrades and pinning: The stack is pinned to the 3.0.100 published images through
DJANGO_VERSION/NGINX_VERSIONin/opt/defectdojo/.env, so it never silently upgrades. - Security patches: unattended-upgrades remains enabled, so the OS continues to receive security updates automatically.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.
This image packages the open source DefectDojo software (BSD-3-Clause License) for convenient deployment on AWS. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by the DefectDojo project or OWASP.
Deploy on AWS
Launch DefectDojo with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com