# Upgrading to DefectDojo Version 2.51.x

## Performance improvements

This release includes multiple improvements aimed at making DefectDojo faster, more scalable, and lighter on your database and workers.

- Import and reimport are significantly more efficient: product grading is now orchestrated in batches using Celery chords, reducing the number of background tasks and database churn during large scans. This means faster imports and smoother post-processing on busy systems. See [PR 12914](https://github.com/DefectDojo/django-DefectDojo/pull/12914).
- Query-count reductions and importer hot-path tuning: we trimmed unnecessary ORM calls and optimized how findings/endpoints are updated during (re)import. You should see noticeably quicker runs out of the box. See [PR 13182](https://github.com/DefectDojo/django-DefectDojo/pull/13182) and [PR 13152](https://github.com/DefectDojo/django-DefectDojo/pull/13152).
- Smarter background task orchestration for product grading: less duplicate work and better scheduling during heavy operations, keeping the UI responsive while long jobs run. See [PR 12900](https://github.com/DefectDojo/django-DefectDojo/pull/12900).
- Bulk tag addition for large batches: adds an internal method to add tags to many findings at once, performing tagging in batches (default 1,000) with only a few queries per batch. This replaces ~3 queries per finding with ~3 queries per batch, significantly reducing DB load during imports, reimports, and bulk edit. On a ~10k-findings sample, import time dropped from ~372s to ~190s. See [PR 13285](https://github.com/DefectDojo/django-DefectDojo/pull/13285).
- Preparations for our switch to `django-pghistory` which provides more features and better performance compared to `django-auditlog`. See [PR 13169](https://github.com/DefectDojo/django-DefectDojo/pull/13169).

No configuration changes are required—gains are automatic after upgrading.

## Helm Chart Changes

This release introduces several important changes to the Helm chart configuration:

### Breaking changes

#### Volume Management Improvements

- **Streamlined volume configuration**: The existing volume logic has been removed and replaced with more flexible `extraVolumes` and `extraVolumeMounts` options that provide deployment-agnostic volume management.

> The previous volume implementation prevented mounting projected volumes (such as secret mounts with renamed key names) and per-container volume mounts (like nginx emptyDir when readOnlyRootFs is enforced). The new approach resolves these limitations.

#### Moved values

The following Helm chart values have been modified in this release:

- `redis.transportEncryption.enabled` → `redis.tls.enabled` (aligned with upstream Helm chart)
- `redis.scheme` → `redis.sentinel.enabled` (controls deployment mode and aligns with upstream chart)
- `redis.redisServer` → `redisServer` (prevents potential schema conflicts with upstream chart)
- `redis.transportEncryption.params` → `redisParams` (prevents potential schema conflicts with upstream chart)
- `postgresql.postgresServer` → `postgresServer` (prevents potential schema conflicts with upstream chart)

### New features

#### Container and Environment Enhancements

- **Added extraInitContainers support**: Both Celery and Django deployments now support additional init containers through the `extraInitContainers` configuration option.
- **Enhanced probe configuration for Celery**: Added support for customizing liveness, readiness, and startup probes in both Celery beat and worker deployments.
- **Enhanced environment variable management**: All deployments now include `extraEnv` support for adding custom environment variables. For backwards compatibility, `.Values.extraEnv` can be used to inject common environment variables to all workloads.

## GitHub Scan Type and Parser Updates

The Github Vulnerability scan type and parser has been split into two distinct scan types:

- [Github Vulnerability](https://github.com/DefectDojo/django-DefectDojo/blob/master/docs/content/supported_tools/file/github_vulnerability.md) (original)
- [Github SAST](https://github.com/DefectDojo/django-DefectDojo/blob/master/docs/content/supported_tools/file/github_sast.md)

The original Github Vulnerability scan type will continue to accept SCA vulnerabilities uploaded in GitHub’s GraphQL format, as it has always done. It will also continue to accept SAST uploads, however we recommend upgrading to the new Github SAST scan type for uploading these types of vulnerabilities going forward. This new scan type will accept the raw JSON response from [GitHub’s REST API for code scanning alerts](https://docs.github.com/en/rest/code-scanning/code-scanning). Sample Github SAST scan data can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/github_sast).

### Other changes

- **Celery pod annotations**: Now we can add annotations to Celery beat/worker pods separately.
- **Flexible secret deployment**: Added the capability to deploy secrets as regular (non-hooked) resources to address compatibility issues encountered with CI/CD tools (such as ArgoCD).
- **Optional secret references**: Some secret references are now optional, allowing the chart to function even when certain secrets are not created.
- **Fixed secret mounting**: Resolved issues with optional secret mounts and references.
- **Improved code organization**: Minor Helm chart refactoring to enhance readability and maintainability.

## PostgreSQL Major Version Upgrade in Docker Compose

This release incorporates a major upgrade of Postgres. When using the default docker compose setup you’ll need to upgrade the Postgres data folder before you can use Defect Dojo 2.51.0.

There are lots of online guides to be found such as https://hub.docker.com/r/tianon/postgres-upgrade or https://github.com/pgautoupgrade/docker-pgautoupgrade.

There’s also the [official documentation on `pg_upgrade`](https://www.postgresql.org/docs/current/pgupgrade.html), but this doesn’t work out of the box when using Docker containers.

Sometimes it’s easier to just perform the upgrade manually, which would look something like the steps below. It may need some tuning to your specific needs and docker compose setup. The guide is loosely based on https://simplebackups.com/blog/docker-postgres-backup-restore-guide-with-examples.

If you already have a valid backup of the postgres 16 database, you can start at step 4.

_Note: If you are using a bound volume, the path has changed for Postgres18. It is now `/var/lib/postgresql/` instead of `/var/lib/postgresql/data`. Failure to change the path may result in errors about failure to create a shim task. See the discussion in [docker-library/postgres](https://github.com/docker-library/postgres/issues/1370)._

> **Postgres Data storage**  
>  
> PostgreSQL 18 changed its default `PGDATA` path from `/var/lib/postgresql/data` to `/var/lib/postgresql/18/docker`. Because the Docker volume was mounted at `/var/lib/postgresql/data`, data was written to the container’s ephemeral layer instead of the volume.  
> This has been fixed in 2.55.4 by explicitly setting `PGDATA: /var/lib/postgresql/data` in `docker-compose.yml`.  
> If you customise the postgres service in your own `docker-compose.override.yml`, make sure `PGDATA` is set to the path where your volume is mounted.  
> **Important for existing installations**  
>  
> If you previously ran DefectDojo with PostgreSQL 18 using the old default `docker‑compose.yml`, your PostgreSQL data may be stored inside a nested directory such as `/var/lib/postgresql/data/18/docker`  
> In that case, the root of the volume (`/var/lib/postgresql/data`) is non‑empty but is _not_ itself a valid Postgres cluster root. After applying the fix that sets `PGDATA: /var/lib/postgresql/data` PostgreSQL may fail to start with an error like `initdb: error: directory "/var/lib/postgresql/data" exists but is not empty` because the existing cluster files still live under the nested versioned path.  
> To fix this problem you can migrate the existing cluster files into the volume root:  
>  
> 1. **Stop the Postgres service**  
>  
> 
> ```sh  
> docker compose stop postgres  
> ```  
> 2. **Verify where your cluster currently lives**  
>  
> 
> ```sh  
> docker run --rm -it -v <your_volume_name>:/data alpine sh  
> ls -la /data  
> ```  
>  
> Look for a directory such as `18/docker` that contains `PG_VERSION`, `base/`, etc.  
> 3. **Move the cluster files into the volume root**  
>  
> 
> ```sh  
> docker run --rm \  
> -v <your_volume_name>:/data alpine \  
> sh -c "mv /data/18/docker/* /data/"  
> ```  
> 4. **Clean up empty folders (optional)**  
>  
> 
> ```sh  
> docker run --rm \  
> -v <your_volume_name>:/data alpine \  
> sh -c "rm -rf /data/18 /data/data"  
> ```  
> 5. **Start Postgres again**  
>  
> 
> ```sh  
> docker compose up -d postgres  
> ```  
> After this, the database should start using `PGDATA: /var/lib/postgresql/data`, and your existing data will be preserved.

### 0. Backup

Always back up your data before starting and save it somewhere.  
Make sure the backup and restore is tested before continuing the steps below where the docker volume containing the database will be removed.

### 1. Start the Old Postgres Container

If you’ve accidentally already updated your docker-compose.yml to the new versions, downgrade to postgres 16 for now:

Edit your `docker-compose.yml` to use the old Postgres version (e.g., `postgres:17.6-alpine`):

```yaml
postgres:
  image: postgres:17.6-alpine
  ...
```

Start only the Postgres container which will now be 17.6:

```bash
docker compose up -d postgres
```

### 2. Dump Your Database

```bash
docker compose exec -t postgres pg_dump -U defectdojo -Fc defectdojo -f /tmp/defectdojo.dump
docker cp <postgres_container_name>:/tmp/defectdojo.dump defectdojo.dump
```

You can find the postgres_container_name via `docker container ls` or `docker ps`.

### 3. Stop Containers and Remove the Old Volume

You can find the volume name via `docker volume ls`.

```bash
docker compose down
docker volume rm <defectdojo_postgres_volume_name>
```

### 4. Switch to the New Postgres Version

Edit your `docker-compose.yml` to use the new version (e.g., `postgres:18-alpine`):

```yaml
postgres:
  image: postgres:18-alpine
  ...
```

### 5. Start the New Postgres Container

```bash
docker compose up -d postgres
```

### 6. Restore Your Database

**Copy the dump file into the new container:**

```bash
docker cp defectdojo.dump <postgres_container_name>:/defectdojo.dump
```

**Restore inside the container:**

```bash
docker exec -it <postgres_container_name> bash
pg_restore -U defectdojo -d defectdojo /defectdojo.dump
```

### 7. Start the Rest of Your Services

```bash
docker compose up -d
```

* * *

There are other instructions for upgrading to 2.51.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.51.0) for the contents of the release.
