Covers upgrading an existing DefectDojo Pro release to a newer chart version.
The recommended path is to pull the chart directly from the DefectDojo OCI
registry — no zip extraction required. The packaged-zip workflow used at
install time also works for upgrades and is documented below.
A DefectDojo Pro release is a chart version, a set of container image
versions, and the Pro settings files. Those are built and tested together and
have to move together. Upgrading the image tags on their own is not supported
and will break the deployment.
The same applies to settings. A new pro_settings.py ships with nearly every
release. Never carry a copy forward across an upgrade, and never hand-patch an
older one: the application has to run the pro_settings.py that matches its
version. Your own customizations belong in local_settings.py, which is
preserved across upgrades and is the only one of the two you should edit.
Using the chart handles this for you. It ships and mounts the matching
pro_settings.py alongside your local_settings.py, so there is nothing to
copy or migrate by hand.
Every upgrade should start the same way. Skipping these steps is the most
common cause of failed upgrades.
Read the release notes for every version between your current release
and the target. Breaking changes, new required fields, and migration
prerequisites are called out there. The GitHub release page for each tag
links to the change log.
Check your current chart version. This is the floor for the upgrade:
helm list -n $NAMESPACEhelm get metadata dojopro -n $NAMESPACE
Back up your database. Chart upgrades can include Django migrations
that alter schema. Take a logical dump (or a storage-level snapshot) of
the PostgreSQL instance before proceeding.
Have your values files available. The upgrade command must pass the
same platform preset, profile preset, and customer values file used at
install. Missing or drifted values files cause surprising diffs.
Confirm secret references still exist. If you installed with
--set dojo.existingSecret=... or --set license.existingSecret=...,
verify those Kubernetes secrets are still present in the namespace.
Render the upgrade locally first to catch missing fields, invalid
values, or template errors before touching the cluster:
$CHART_REF is the OCI reference (see below) or the extracted chart path.
Set NAMESPACE once — every command in this guide uses $NAMESPACE:
NAMESPACE="dojopro"
Network policy default changed. NetworkPolicies are now governed by
networkPolicy.profile, which defaults to standard: all egress plus
ingress between this release’s own pods is allowed (external ingress is still
restricted to the ingress path). This is more permissive than the previous
always-granular egress allowlist. To keep the locked-down behavior, set
networkPolicy.profile: aggressive and review the carve-outs
(nodeLocalDns, dnsSelectors, externalAPIs) — see
Network Policies.
Orchestrator database requirement. The orchestrator (ddorch) uses a
second database named <main-db-name>-ddorch and creates it at startup if
it does not exist. If your application role lacks CREATEDB, pre-create it
(CREATE DATABASE "defectdojo-ddorch" OWNER defectdojo;) before upgrading
to a chart version that enables ddorch — otherwise the ddorch pod fails with
permission denied to create database (SQLSTATE 42501). See
Pre-flight: Orchestrator (ddorch) Database.
Organization/Asset relabel default.dojo.V3EnableOrganizationAssetRelabel
now defaults to null (auto): it is enabled for new installs and left
off on upgrades, so the UI relabel (Organization/Asset replacing
ProductType/Product) never flips on unexpectedly for an existing release. To
opt an upgraded release in, set dojo.V3EnableOrganizationAssetRelabel: true
explicitly; an explicit true/false always wins over the auto default.
Each release is tagged with the chart version (for example 2.57.2). The
chart version matches the app version in Chart.yaml, so the tag you pass
to helm upgrade --version is the same version number shown on the GitHub
release.
List available chart versions:
helm show chart \
oci://us-south1-docker.pkg.dev/defectdojo-container-registry/dojo-pro-helm-v2/dojopro \
--version <chart-version>
Why OCI for upgrades? The presets (presets/platforms/*.yaml,
presets/profiles/*.yaml) are packaged inside the chart. Referencing the
chart by its OCI URL pulls the correct preset versions for the target
chart automatically — no re-extraction step, no stale presets.
The registry is private. Helm must be logged in before it can pull the
chart. Use a GCP service-account key or short-lived access token provided
by DefectDojo support.
Access tokens from gcloud auth print-access-token expire after one hour.
Re-run helm registry login if you see a 401 Unauthorized during the
upgrade.
Air-gapped / firewalled environments: if your cluster nodes can reach
us-south1-docker.pkg.dev but your workstation cannot, use the
extracted-zip workflow below. The OCI workflow only works when the host
running helm upgrade can reach the registry.
Point helm upgrade directly at the OCI URL and pin the chart version with
--version. All values files, --set flags, and --set-file flags are the
same as the original install.
The platform and profile preset paths above are presets/platforms/...
(no $CHART/ prefix). When Helm pulls a chart from OCI, the presets live
inside the pulled chart, but -f here points at local copies of those
files. If you do not keep local copies of the presets, extract the chart
first with helm pull oci://... --version $VERSION --untar and reference
them from the extracted directory — or use the extracted-zip workflow.
Always pin --version. Omitting it pulls whatever tag the registry
resolves to at the moment of the command — not repeatable, not
auditable. Pin the version so reruns, rollbacks, and incident response
all reference the same artifact.
For workstations that cannot reach the OCI registry, or for customers who
prefer to stage the chart as a local file, the packaged zip from the GitHub
release works the same way at upgrade time as it does at install time. The
only difference from install is the command verb (helm upgrade instead of
helm install).
Download dojo-pro-helm-bundled-<version>.zip (and the detached
signature .asc) from the GitHub release.
Verify the signature using the public key
(dojo-pro-release-signing.asc) as documented in the install guide.
Extract the chart to a versioned path so presets do not collide with
older extractions:
unzip dojo-pro-helm-bundled-<version>.zip -d /tmp/dojopro-<version>
cd /tmp/dojopro-<version>
mkdir -p dojopro-<version>
tar -xzf dojopro-<version>.tgz -C dojopro-<version>/
CHART="/tmp/dojopro-<version>/dojopro-<version>/dojopro"
Run the upgrade using the extracted chart path — same values files and
flags as your original install:
Re-extract on every upgrade. Preset files evolve between chart
versions. Reusing an old extraction silently pins your upgrade to the old
preset defaults.
When DefectDojo Pro is managed by ArgoCD, upgrading is a single change to
targetRevision in the Application spec. The platform and profile presets
are versioned inside the chart, so they update in lockstep.
Sync the Application after editing targetRevision. ArgoCD will pull the
new chart from the OCI registry and reconcile.
ArgoCD needs its own credentials to the OCI registry. Configure the repo
secret with type: helm and enableOCI: "true". See the ArgoCD
Helm OCI docs
for the exact Secret shape.
After helm upgrade returns (or ArgoCD reports Synced / Healthy), confirm
the new revision is live:
# Chart revision bumped and status is deployedhelm list -n $NAMESPACE# All pods Running and Ready — expect django, celery worker/beat,# connectors, ddorch, ddorch-workers, and (if enabled) mcp-serverkubectl get pods -n $NAMESPACE# Migrations succeeded — the initializer job should show Completedkubectl get jobs -n $NAMESPACE# App version matches the targetkubectl get deployment -n $NAMESPACE\
-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.template.spec.containers[*].image}{"\n"}{end}'
Hit the login page to confirm the UI comes up and the admin user can
authenticate. For programmatic checks, the /login/ endpoint returns 200
when the app is healthy.
Helm keeps release history by revision. If the upgrade regresses behavior,
roll back to the previous revision:
# Inspect historyhelm history dojopro -n $NAMESPACE# Roll back to the previous revisionhelm rollback dojopro <previous-revision> -n $NAMESPACE --wait --timeout 15m
Database migrations do not roll back. Helm rollback restores the
manifest state (images, configs, secrets) but does not run
migrate --revert. If the upgrade applied a schema migration you need
to reverse, restore from the backup taken in
Before You Upgrade or coordinate a manual
migration reversal with DefectDojo support before rolling back the
Helm release.
ArgoCD users can roll back by reverting the targetRevision change in
git (or via argocd app rollback) and syncing.
401 Unauthorized pulling the chart.
Access token has expired. Re-run helm registry login with a fresh
gcloud auth print-access-token.
Error: UPGRADE FAILED: cannot patch ... field is immutable.
A selector or other immutable field drifted. The chart pins stable
selector labels, so this usually means a prior in-place edit to a
Deployment. Capture the diff, delete the offending resource, and re-run
the upgrade so Helm recreates it.
Error: UPGRADE FAILED: conflict occurred while applying object ... conflict with "kubectl-edit" ... .spec.replicas.
Helm 4 uses server-side apply, which tracks field ownership. This error
means another manager — kubectl edit, kubectl scale, or the HPA
controller (kube-controller-manager) — changed a field Helm renders,
most commonly .spec.replicas. Take ownership back once:
helm upgrade ... --force-conflicts
Chart versions with this fix omit replicas from Deployments whose HPA
is enabled, so the HPA scaling no longer conflicts with upgrades. If you
manually scaled a Deployment with kubectl, prefer adjusting the
corresponding replicas/horizontalpodautoscaler value instead so the
chart stays the owner.
Error: UPGRADE FAILED: timed out waiting for the condition.
Pods did not reach Ready within the --timeout window. Inspect the
laggy workload:
Common causes: image pull failures (registry auth), schema migration
still running (bump --timeout), or readiness probes failing against a
mis-configured FQDN.
Preset changed between versions and my values file now conflicts.
Re-render with helm template (see Before You Upgrade)
and reconcile your overrides against the new preset defaults before
running helm upgrade.
values don't meet the specifications of the schema ... got string, want boolean.
An on/off value in your override is quoted. Helm treats "false" as a
non-empty string, and a non-empty string is truthy, so the feature was
switching on when you meant to switch it off. The schema now rejects
the quoted form instead of letting it through. Drop the quotes:
networkPolicy:enabled:"false"# wrong: turns network policies ONenabled:false# right
The error message names the offending path. Unquoted false, no, and
off all parse as a real boolean and are accepted.