Upgrading DefectDojo Pro (On-Premise) (Pro)
This page describes the supported upgrade procedure for self-hosted DefectDojo Pro. It applies to both deployment methods; the detailed, method-specific steps live on their own pages:
- Kubernetes (Helm chart): DefectDojo Pro Upgrade Guide
- Docker Compose (
dojo-compose-cli): DefectDojo Pro Upgrade Guide (Docker Compose)
Upgrade everything as one unit
Each DefectDojo Pro release consists of container image versions, deployment files (the Helm chart or the Docker Compose deployment files), and the Pro settings files. These are built and tested together and must be upgraded together as one unit.
Upgrading only the image tags is not supported and will break your deployment.
Settings files and upgrades
DefectDojo Pro ships a pro_settings.py file with every release, and the file changes with nearly every version. Do not carry a copy of pro_settings.py forward across upgrades, and do not patch an older copy by hand. The application must always run the pro_settings.py that matches its version.
Put your own customizations in local_settings.py, never in pro_settings.py. Your local_settings.py is preserved across upgrades. Both deployment methods ship and mount the matching pro_settings.py and your local_settings.py automatically, so there is nothing to copy or migrate by hand.
Supported upgrade procedure
- Review the release notes for every version between your current version and your target version, not just the target itself. See the DefectDojo Pro Changelog and the version-specific upgrade notes.
- Back up your database, and the rest of what Backing Up a Self-Hosted Deployment lists. If an upgrade has to be undone, Restoring a Self-Hosted Deployment covers bringing that backup back.
- Follow the steps for your deployment method: Kubernetes (Helm) or Docker Compose. Do not change image tags independently of the release.
Upgrading across several releases
You do not need to install the releases in between. Upgrade straight to the target: the initializer applies every database migration between your current version and the target in a single run. The release notes of the versions you skip still apply, which is why step 1 above asks you to read all of them.
A jump across many releases runs many migrations, some of which rewrite data in large tables, so plan for it:
- Back up both databases, the main one and its
-ddorchcompanion, together with the configuration and keys. See Backing Up a Self-Hosted Deployment. - Rehearse on a copy. Restore that backup into a separate environment on your current version, then run the upgrade there. The time the initializer takes on the copy is the best estimate of your maintenance window, and any problem it hits shows up before production does.
- Keep the restore and the upgrade apart. A backup comes back on the version that wrote it; upgrading is a second step. See Restoring a Self-Hosted Deployment.
- Migrations do not roll back. Rolling the deployment back to the old version leaves the database on the new schema. To go back, restore the backup you took before the upgrade.
- On Kubernetes, consider holding the pods until the migrations finish. By default the new pods start while the initializer is still migrating, so for a while new code runs against the old schema. Setting
dojo.migrationCheck.enabled: truein your values makes each application pod wait for the migrations first, at the cost of a longerhelm upgrade --wait. The Kubernetes upgrade guide covers the--timeoutthis needs.
Revoked releases
Now and then a release ships with a problem serious enough that nobody should stay on it, and a later release fixes it. That release is then revoked. Its container images are never deleted or retagged, so a deployment already running it keeps working, can restart, and can roll back. What changes:
- In DefectDojo, users who can see the Version Manager get a banner on every page naming the revoked release, the reason, and the release to upgrade to. The Version Manager never offers a revoked release as the latest version.
- The deployment CLIs refuse to install or upgrade to a revoked release, and name the release to use instead. Choosing a revoked release on purpose, for example to roll back to it, needs
--allow-revoked. - The DefectDojo Pro Changelog marks the release with a note giving the reason and the release to upgrade to.
To leave a revoked release, follow the supported upgrade procedure to the release the notice names.
DefectDojo reads the list of revoked releases about once an hour from a signed public feed at https://intel.defectdojo.com/releases/revocations.json. An air-gapped instance does not read it, so check the changelog before choosing a target version. A forward proxy that blocks that address only hides the banner; nothing else depends on it.
Reading the initializer’s result
Every upgrade runs the initializer once before the application starts: the init container on Docker Compose, the initializer Job on Kubernetes. It applies the database migrations and then runs DefectDojo’s system checks. Its exit code says how far it got:
| Exit code | Migrations | System checks | What to do |
|---|---|---|---|
0 | All applied | Passed | Nothing. The upgrade is complete. |
2 | All applied | At least one failed | Fix the configuration problem the log names, then start the initializer again. The database is already upgraded, so do not restore your backup to retry the upgrade. |
1 | Check the summary | Not run | Something other than a system check failed: a migration, or a step before or after the migrations (for example the cache or a data seed). The migration summary printed just before the exit shows whether every migration applied. Fix the cause the log names and start the initializer again. Restore your backup only when the summary shows unapplied migrations that cannot be completed. |
On a non-zero exit the initializer prints the migration state of each app before it stops, so the log shows whether the database was upgraded. Abridged example (the real output lists every app):
Migration state (manage.py showmigrations --skip-checks lists every migration):
dojo: 301 of 301 applied
pro: 250 of 251 applied (not applied: 0251_example)To see the code after the fact:
- Docker Compose:
docker inspect --format '{{.State.ExitCode}}' init - Kubernetes:
kubectl get pod -n <namespace> -l app.kubernetes.io/component=initializer -o jsonpath='{.items[*].status.containerStatuses[*].state.terminated.exitCode}'
When DD_INITIALIZE=false skips the migrations, exit code 2 still means a system check failed, and the database is unchanged.
The initializer needs a valid license
From release 3.4.200, the initializer checks for a DefectDojo Pro license before it migrates anything, on a first install as well as on every upgrade. It looks in three places, and one valid license in any of them is enough:
- the
DD_LICENSEenvironment variable; - the license file
/opt/dojo/pro/dojopro.lic, which the Helm chart mounts from its license Secret and Docker Compose mounts from the install’slicense/directory; - the license already stored in the database by an earlier install or a license update.
An expired license still counts: expiry is handled by the application as before. When none of the three holds a valid license, the initializer exits 1 without changing the database and lists what it checked:
[NO_VALID_LICENSE] No valid DefectDojo Pro license was found, so nothing was migrated and the database is as it was. Checked:
- DD_LICENSE is not set
- /opt/dojo/pro/dojopro.lic does not exist
- the database has no Pro license table yet (a new or Community database)Provide the license and start the initializer again. The license must be in place before the first Pro initializer runs: when converting a Community database to Pro, and on a new Helm install, where leaving license.contents at the chart’s placeholder value now stops the install instead of starting it without a license. To check without starting the initializer, run python manage.py check_license_present in a DefectDojo container.
If you have questions about upgrading your on-premise deployment, contact support@defectdojo.com.