> ## Documentation Index
> Fetch the complete documentation index at: https://docs.casebender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Upgrading CaseBender

> Safely upgrade your CaseBender deployment to the latest version without losing data, licenses, or credentials.

## Overview

CaseBender ships as a set of versioned container images. Upgrading means pulling
the latest images and recreating the containers. Your data, license, and
configuration live in **named Docker volumes** and your **`.env` file** — both are
preserved across upgrades, so an upgrade never touches your cases, users,
credentials, or license as long as you keep them.

<Note>
  Database migrations and default-data seeding run automatically on startup after
  every upgrade. You do not need to run any migration commands manually.
</Note>

## What persists across upgrades

| What                           | Where it lives             | Preserved by               |
| ------------------------------ | -------------------------- | -------------------------- |
| Cases, alerts, users, settings | PostgreSQL                 | `pgdata` volume            |
| License secret key + blob      | `/app/apps/web/app/secret` | `casebender_secret` volume |
| Uploaded files / attachments   | MinIO                      | `miniodata` volume         |
| Queue / cache state            | Redis                      | `redis_data` volume        |
| Environment configuration      | `.env`                     | your `.env` file           |

<Warning>
  Never run `docker compose down -v` on a production system. The `-v` flag deletes
  all named volumes — your database, license, and files. Without those volumes, the
  next start creates a fresh database, which resets the admin password to the
  default and regenerates the license.
</Warning>

## Upgrade procedure (Docker Compose)

<Steps>
  <Step title="Back up your database and .env">
    ```bash theme={null}
    # Back up PostgreSQL
    docker compose exec -T db pg_dump -U superadmin casebender > casebender-backup-$(date +%F).sql

    # Keep a copy of your configuration
    cp .env .env.backup
    ```
  </Step>

  <Step title="Pull the latest images">
    ```bash theme={null}
    docker compose pull
    ```
  </Step>

  <Step title="Recreate the containers">
    ```bash theme={null}
    docker compose up -d
    ```

    Compose recreates only the services whose image changed and keeps your volumes.
  </Step>

  <Step title="Watch the logs">
    ```bash theme={null}
    docker compose logs -f app
    ```

    Migrations and seeding run on boot — wait for the app to report healthy.
  </Step>
</Steps>

## Verify after upgrading

* Sign in and confirm your existing cases, alerts, and users are present.
* Confirm your login still works (your admin password is unchanged).
* Check the worker is processing jobs:

```bash theme={null}
docker compose logs worker | tail
```

## Rollback

If something goes wrong, pin the previous image tag and restore your backup:

```bash theme={null}
# Pin the known-good version in docker-compose.yml, e.g.
#   image: casebender/casebender:vX.Y.Z
docker compose pull
docker compose up -d

# If needed, restore the database backup
cat casebender-backup-YYYY-MM-DD.sql | docker compose exec -T db psql -U superadmin casebender
```

<Note>
  Always upgrade a staging environment first, and take a fresh database backup
  immediately before upgrading production.
</Note>

## Common upgrade mistakes

The two most common problems both come from losing state:

* **Changing the Compose project name or directory.** Docker derives volume names
  from the project. Renaming the folder or using a different `-p` project name
  points Compose at *new, empty* volumes. Always upgrade from the same
  directory/project so your existing volumes are reused.
* **Missing `LICENSE_SECRET_KEY` and no `casebender_secret` volume.** On older
  deployments without the persistent secret volume, set `LICENSE_SECRET_KEY` in
  `.env` (or add the volume) so the license survives. Current deployments persist
  it automatically.

## Desktop Installer

If you deployed with the Desktop Installer, use the app's built-in update flow —
it pulls the latest images and recreates services while preserving your data
directory, `.env`, and license key.

## Google Cloud Run

Cloud Run upgrades deploy a new revision. Because Cloud Run has an ephemeral
filesystem, the license secret must be provided via **Secret Manager** as
`LICENSE_SECRET_KEY` so it persists across revisions. Redeploy against your
existing Cloud SQL instance and secrets:

```bash theme={null}
gcloud run deploy casebender-web --image <new-image> --region <region>
```

Migrations run automatically on the new revision.
