Skip to main content
CID222 Docs

Upgrade to 0.4.0

Move an appliance or a Docker Compose installation from 0.3.x to 0.4.0, know what the first boot does to the schema, and understand what a rollback does and does not return.

  • Version: 0.4
  • Role: admin_user
  • Type: task

Every 0.3.x installation moves to 0.4.0 in one step — the release declares no minimum version to upgrade from. What differs is who applies it: an appliance is updated from the dashboard, and a Docker Compose installation is updated from a shell on its own host.

What do I need?

Licence
Any
Role
admin_user

Prerequisites

  • You know which of the two installations you have: an appliance carries Settings → System Updates and a privileged updater on its host; a Compose installation is a git checkout the operator maintains.
  • A current backup that is not on the appliance's own disk. See Backup and restore.
  • A maintenance window. Migrations run before the new containers start, so the still-serving old version runs into their locks and writes can block.
  • For an appliance on the online path: it can reach the release channel over HTTPS.
  • For an appliance that is air-gapped: the signed .cidupd bundle for 0.4.0, on a machine whose browser can reach the appliance.
  • For a Compose installation: shell access with permission to run Docker, and a clean git working tree — update.sh refuses to run on a dirty one.

What the first 0.4 boot does to your database

DB_SYNCHRONIZE now defaults to false, and the container entrypoint applies the TypeORM migration chain on boot whenever it is not true. On an appliance this is unremarkable — the release chain has always owned the schema. On a Compose box that never set the variable, it means the first 0.4 boot stops letting TypeORM reshape the schema on every restart and instead stamps the baseline and runs the whole chain, for most such boxes the first migration run they have ever done.

A failure there is fatal on purpose: the container refuses to boot rather than serve against a schema it could not migrate.

Warning

Auto-sync drops every index and trigger the migrations create, because no entity declares them. Keeping the old behaviour with DB_SYNCHRONIZE=true is possible and is not supported going forward.

Upgrade

Take a backup that is not on the appliance

Snapshot the virtual machine with it powered off, or take the file-level copy described in Backup and restore.

The updater takes its own database backups immediately before it applies a release — a compressed logical dump and a physical snapshot of the data directory, both under /var/lib/cid/backups, with the last 14 dumps kept. Those live on the appliance's own disk and cover the database alone, so they are an update safety net rather than the backup this step asks for.

Apply the release

Follow Update the appliance, on the online path or from the signed bundle.

The page streams the updater's progress and shows a duration estimate derived from the size of your database and the number of migrations actually pending.

Let the host repair finish

Stay on Settings → System Updates until the Host repair tile reports its migrations as applied.

0.4.0 introduces host-side repair: a signed release can now replace the updater, install systemd units and correct the deployment mode on a box installed from an older image. A box coming from 0.3.x has repairs to run, and some of them wait for the updater to go idle before they apply.

What a rollback returns, and what it does not

Rollback behaves differently on the two installations, and neither of them undoes a schema migration.

ApplianceDocker Compose
Triggered byYou, from Settings → System Updates, or automatically when the new release fails its health gateupdate.sh automatically, when the health wait times out
Restores the databaseYes, from the snapshot taken before the release was appliedYes, from the pg_dump taken at the start of the run
Restores the previous imagesYesNo — the new containers are left running so their logs survive
Data written since the updateLostLost

Danger

A rollback restores the database as it was before the update. Sessions, detections, event log entries and configuration changes recorded since are gone. Roll back to recover from a broken update, never to undo a configuration mistake.

On a Compose installation the automatic path is a database rollback only, so a failed update leaves 0.4.0 images running against a 0.3.x database. Treat exit code 5 from update.sh as an incident to finish by hand: read the logs it printed, and either fix forward or restore the whole box from the backup you took in step 1.

Verify

  1. Settings → System Updates shows 0.4.0 under Installed version, and Last update reports the run as successful. On a Compose box, curl localhost:3000/health answers 200.
  2. No migrations are pending. On a Compose box, make migration-status lists none; on an appliance, the Host repair tile lists none as pending or failed.
  3. docker compose ps shows every container healthy, and a hallucination-guard container is among them.
  4. Settings → License still shows your tier and expiry. An upgrade never changes the licensed package.
  5. Send one chat request that contains a piece of test PII. It is masked or rejected according to your filters, and the detection appears under All Detections.

If it fails

The gateway will not boot and the log names a migration:

Runbookdata

Migrations are pending, and the pages that read the new columns fail

You might see: compiled migration(s) have never been applied to this database · one page returns 500 while the rest of the product works · column does not exist · relation does not exist

Before you start

Checks

  1. 1

    Read the list of compiled migrations that are not recorded in the database

    diagnostics · datastores.postgres.migrationsPending

  2. 2

    Verify auto-synchronise is off, since it hides an unapplied chain behind a schema that looks right

    diagnostics · posture.dbSynchronize = false

  3. 3

    Verify the gateway is not restarting, which is what a failing boot migration usually produces

    diagnostics · containers[nestjs-core].restarts = 3

The schema lost its indexes, or the box was running with auto-sync:

Runbookdata

The database schema is being auto-synchronised on every boot

You might see: DB_SYNCHRONIZE=true · indexes disappear after a restart · search is slow again after every reboot · the schema changes without a migration

Before you start

Checks

  1. 1

    Read the effective auto-synchronise setting

    diagnostics · posture.dbSynchronize = false

  2. 2

    Verify the migration chain is fully applied, since auto-sync hides an unapplied chain

    diagnostics · datastores.postgres.migrationsPending

The appliance update page reports a failure, or a version of 0.0.0:

Runbookupdates

The System Updates page shows 0.0.0, or the update buttons return 500

You might see: System Updates shows version 0.0.0 · current version 0.0.0 · update check returns 500 · install update → 500

Before you start

Checks

  1. 1

    Read the product version the appliance reports

    diagnostics · appliance.version = "0.0.0"

  2. 2

    Verify an update channel is configured

    diagnostics · appliance.channel

  3. 3

    Verify the release channel answered on the last attempt

    diagnostics · appliance.update.channelReachable = true

  4. 4

    Check whether an update or host-repair intent is stuck waiting for the host updater

    diagnostics · appliance.update.pendingIntent

  5. 5

    Read the host-repair status, which is what the page renders alongside the version

    GET /admin/system-update/host-repair

The appliance cannot reach the release channel:

Runbookupdates

The update channel is not reachable from the appliance

You might see: The update channel host is not reachable from inside the gateway · Check for updates does nothing · update check returns 500 · the appliance never finds a new version

Before you start

Checks

  1. 1

    Verify an update channel is configured at all

    diagnostics · appliance.channel

  2. 2

    Read whether the channel answered on the last attempt

    diagnostics · appliance.update.channelReachable = true

  3. 3

    Read the name-resolution results for the hosts the appliance must reach

    diagnostics · appliance.dns

  4. 4

    Read whether an outbound proxy is configured, on a network that requires one

    diagnostics · appliance.proxy.configured = true

Next steps

Last updated on

On this page

Download PDF