Upgrades

An upgrade is: back up one file, replace the binary or image, restart. There is no migration command, no online component and no upgrade wizard. This page says what happens to each kind of state when you do, what you will see while a new release settles in, and how to go back.

What an upgrade touches

Everything the product keeps lives under instance.dataDir, and only one thing there is durable in the sense that it cannot be rebuilt.

What Where On upgrade
Users, local accounts, API keys, OAuth refresh tokens, connection records subjects.db Kept. The schema is brought up to date at startup, additively.
Clones repos/ Kept. Nothing is re-cloned; the scheduler carries on fetching.
Deep-analysis results analysis/ Kept, or recomputed if the release changed what analysis produces.
Search indexes memory Rebuilt after every restart, upgrade or not.
Your configuration searchcode.yaml, conf.d/ Untouched. Validated at startup.
Audit records written to files audit/ Untouched.

subjects.db is the one to protect. Everything else is a clone of your code hosts or derived from one, and comes back on its own.

Before you start

  1. Back up subjects.db with SQLite's online backup, or stop the service and copy it. Do not cp it while the process is running. See Backup and restore.

  2. Validate your configuration against the new binary before you restart onto it:

     searchcode --config /etc/searchcode/searchcode.yaml config validate
    

    It prints every problem rather than the first, exits non-zero on any, and makes no network call, so it is safe to run anywhere the new binary is.

  3. Keep the old release's codes.json. Every log line carries a code that identifies where it was emitted, and a code from an old log resolves against the build that wrote it. See Log codes.

Configuration compatibility

The configuration file is strict: an unknown key is a startup failure, naming the key and the line. A file that silently dropped a block it did not recognise — an authz block, say — would be far worse than one that refuses to start.

That strictness cuts both ways across releases. Running config validate with the new binary tells you before the restart whether anything in your file needs to change. Going back to an older release with a file that uses a key the older one does not know makes it refuse to start, naming the key: remove the key, or keep the newer release.

The database schema

subjects.db is SQLite. Its schema is applied at every startup, one statement at a time, and every change is additive: new tables are created if they do not exist, and new columns are added to existing tables. There is no separate migration step and nothing to run by hand.

Re-analysis after an upgrade

Each release stamps the deep-analysis results it writes with an analysis version. When a release changes what analysis produces — a security rule's meaning or severity, what a technology detector matches, a new kind of symbol a parser extracts — the version moves. Stored results with the old stamp are then discarded, and each repository's deep pass runs again in the background.

Not every release moves it. When it has not moved, an upgrade re-analyses nothing.

While a re-analysis runs:

How long it takes depends on the estate and on analysis.deepConcurrency; see Sizing. It is the same work as the first analysis after install.

A change to the bundled security rule set alone is handled more gently: the stored results stay in service, and a fresh deep pass is queued behind them.

Search indexes after a restart

The search indexes are held in memory and are never written to disk, so they are rebuilt after every restart. A repository whose index is not built yet is searched by reading its files, which gives the same results more slowly. Nothing is reported as missing. searchcode_search_index_warming is 1 while builds are running.

Upgrading, by install method

Tarball with systemd

searchcode --config /etc/searchcode/searchcode.yaml config validate   # with the NEW binary
sudo systemctl stop searchcode
sudo install -m0755 bin/searchcode /usr/local/bin/searchcode
sudo systemctl start searchcode

State stays in /var/lib/searchcode. Nothing else in the tarball needs to be re-run. The shipped unit gives the process 45 seconds to drain on stop. See Install on a VM with systemd.

Helm

helm upgrade searchcode ./deploy/helm/searchcode \
  --namespace searchcode --values my-values.yaml

Leave image.tag empty in your values: it resolves to the chart's app version, so upgrading the chart is upgrading the product, and an install never drifts onto a different build when a node is replaced. Never set it to latest.

The chart's Deployment uses the Recreate strategy. The data volume is ReadWriteOnce, so a rolling update would deadlock: the new pod cannot attach the volume until the old one lets go. The cost is a few seconds without a pod during the upgrade. Take a volume snapshot of the PVC first; it is the simplest correct backup. See Install with Helm.

Container image

Pull or load the new image, stop the old container, and start the new one with the same dataDir volume and the same configuration mounts. For an air-gapped registry, mirror the new image first. See Air-gapped install.

After the restart

  1. The three listeners announce themselves on stderr, and /readyz returns 200 as soon as the instance can serve. It does not wait for the estate.
  2. searchcode version prints the build and the set of languages it parses; check it is the build you meant to deploy.
  3. Sign in, run a search, and call one MCP tool with an existing key. OAuth refresh tokens and API keys are in subjects.db, so agents stay signed in.
  4. Watch analysis.coverage if the release moved the analysis version.

searchcode doctor runs without a running instance and is the first thing to try if something looks wrong. See searchcode doctor.

Rolling back

Going back to the previous release is the same procedure in reverse, with two things to know:

And the configuration point from above: a key added for the newer release must come out before the older one will start.

Licences and versions

A licence can name the last version it covers. Upgrading past it does not break anything: indexing pauses, and search, the API, MCP, the audit log and authorisation keep working. Check before upgrading with searchcode license show; see Licensing.

Generated from the documentation that ships with searchcode enterprise. Questions: ben@boyter.org