Skip to main content

Upgrades

An upgrade is one command. This page is about the handful of things that make that command safe to run against an install with real data in it.

Upgrade checklist

The whole procedure, in order. Each step links to the detail below.
  1. Read the release notes for every version between yours and the target, and prepare your values file from the new version’s preset (Before you run it, step 1).
  2. Check the chart file is the version you expect: helm show chart $SWARMD_CHART.
  3. Back up both databases and the swarmd-generated-credentials Secret, and note the current Helm revision — it is the one you would roll back to.
  4. Preview the upgrade with --dry-run=server (or helm diff).
  5. Upgrade in a quiet window, with --wait --timeout 15m.
  6. Verify straight away: pods Running with zero restarts, helm test passes, and one real message reaches an agent (Verifying afterwards).
  7. Do any after-upgrade steps the release notes list.
If something is wrong afterwards, contact us first: fixing forward keeps everything created since the upgrade. Rolling back means restoring the backup from step 3.

Getting the new version

We send you a new swarmd-<version>.tgz for each release, with notes covering what changed and anything that needs care on the way to it. There is no registry to poll and no --version flag: the file is the version. That has a couple of practical consequences.
  • Keep old tarballs. helm rollback restores the previous revision from what Helm already has, so it works without the file. Reinstalling an older release from scratch does not — that needs the tarball again, and asking us for it is a slower path than keeping a copy.
  • Name your releases after the file. helm -n swarmd list shows the chart version, so a cluster can always tell you what it is running; keeping the tarballs in one directory makes it just as easy in the other direction.
Read the release notes for every version between where you are and where you are going — not just the target. Helm applies one jump; the notes are written per version.
Anything a particular version needs from you on the way through — a new setting, extra capacity, a step after the upgrade — is in its release notes.
Check the file before you run it against a live install:
It prints the name, version and appVersion in two lines, which is the quickest way to catch a stale download or the wrong file in ~/Downloads.

What survives an upgrade


The one that bricks installs

The chart generates swarmd-generated-credentials on first install and, on every upgrade, reads the existing Secret back so nothing rotates. That read is a Helm lookup, and lookup only works when Helm has a live connection to the cluster. When it doesn’t, every credential falls through to a freshly generated random value. Applying that render rotates the Postgres password, the Keycloak admin password and encryption-key in a single step. The first two stop the platform; the third is worse, because registry, relay and teams encrypt rows at rest with that key and a rotated key makes existing rows permanently unreadable. No backup of the database helps — you need the old key. The chart now refuses rather than letting that happen:
Two situations produce it.
Plain --dry-run is client-side and disables lookup. Use --dry-run=server when you want to preview an upgrade — it keeps the cluster connection, so the Secret is read and the render matches what a real upgrade would apply.
Argo CD renders charts with helm template by default and applies the output. lookup returns nothing in that mode, and because the render reports itself as an install the guard cannot tell it apart from a genuine first install — so it does not fire, and the rotation happens silently.If you deploy through a template-and-apply GitOps tool, do not let the chart own its credentials. Turn generation off and manage the Secret yourself:
Then pre-create a Secret of that name with the keys listed in Configuration → Secrets, sourced from your secret manager (Vault, OpenBao, External Secrets). This is the right shape for GitOps anyway — the credentials stop being a side effect of a render.
Back up encryption-key before your first upgrade, separately from your database, and keep it somewhere a cluster failure cannot take with it.

Before you run it

1

Prepare your values file

Start from the preset that ships with the version you are moving to, then re-apply your own changes, rather than reusing your old file as it is: new versions add settings that an old file silently leaves out. Compare the two:
The release notes list anything a version needs from you, such as a new setting to fill in or extra node capacity.
2

Take a database backup

Migrations run forwards only. There is no down script, so a rollback of the chart does not roll back the schema — see Rolling back. For the single in-cluster Postgres (schema-per-service with sharedDatabase: swarmd):
Note the current revision too — it is the one to roll back to:
Other layouts (a separate or managed database): see Databases › Backups, and Restoring for the rules a restore must follow.
3

Back up the keys

Keep it outside the cluster. A database restore is useless without the matching encryption-key / encryption-keys.
4

Confirm you can read the credentials Secret

If this is missing, stop. Restore it before upgrading.
5

Preview the change

It must finish without an error. The chart checks your values here and refuses, with the reason and the fix, anything that would break the install — the relay allowed to reach every service in the cluster, agent telemetry without ClickHouse, credentials it cannot read back. Use --dry-run=server, never plain --dry-run (see The one that bricks installs).For a line-by-line view of what will change, helm diff upgrade with the same arguments is better still; it is a plugin (helm plugin install https://github.com/databus23/helm-diff).
6

Check you have headroom for the ECR pull

The licence bootstrap Job refreshes the image-pull Secret as a pre-upgrade hook, so an expired registry token is not a problem. A licence that has expired is — the Job fails and the upgrade stops before touching any workload. Check the expiry on your licence first.

What happens during the rollout

Services are replaced in place rather than surged: maxSurge: 0, maxUnavailable: 1. That means a single-replica service is briefly unavailable while its pod is replaced — roughly 40–70 seconds for a JVM service. It is deliberate. The Kubernetes default starts a second pod before retiring the first, which doubles the memory every service wants at the same moment; on a node sized for the steady state the kubelet starts OOMKilling, and it kills the old pods too. A routine upgrade takes down a working install. If you need a genuinely zero-downtime rollout, run more than one replica and put the surge back on that service — and size the node for the surge:
Expect to see, in order:
  1. Migration Jobs run to completion (pre-upgrade hooks, Flyway, forwards only). A service with worker.enabled: false — every service in values-prismforce-local.yaml — has no Job and migrates as its pod starts instead.
  2. Pods replaced one service at a time, each held at Init:0/1 until Keycloak’s realm answers.
  3. The realm bootstrap Job for the new revision runs and exits early, because the realm already exists.
Zero restarts is the expected outcome. A pod that restarts during an upgrade is a signal, not noise — check kubectl -n swarmd describe pod for exit code 137 (OOMKilled) and see JVM sizing.

Rolling back

Talk to us before you roll back a version. Going back to an older version means restoring the database you backed up before upgrading, and everything created since — agents, conversations, audit events — is lost. Most problems after an upgrade are fixed faster, and without losing data, by a configuration change or a patch release.
First find the revision you are going back to. Always name it. Without a revision, helm rollback goes to the previous revision, and that is only the version you came from if nothing has been applied since. After a first rollback attempt, or a second helm upgrade to change a value, “previous” is the new version again.
This restores that chart revision — image tags, resource limits, settings, all of it.
It does not roll back the database. Flyway migrations are forwards-only, so after a rollback the schema is still the new one while the images are the old ones. That is fine for additive migrations and is not fine for anything that dropped or renamed a column, or for data the older version cannot read.Treat helm rollback on its own as the fast path for a configuration mistake or a bad image within the same version, and your database backup as the recovery path when you are going back a version. A version’s release notes say when going back past it needs a restore.

Rolling back with a restore

Run this from the directory holding the dumps you took before upgrading, straight after the helm rollback above. It is self-contained: it reads the Postgres credentials itself, and it puts every workload back at the replica count it had.
Restore into an empty database, never over the upgraded one. An earlier version of this page used pg_restore --clean. That cannot drop tables the newer version added when they reference the older ones, so it skips them, then appends the backup’s rows into tables that were never emptied: agents appear twice, primary keys are lost, and the registry answers 500 for every agent. --exit-on-error --single-transaction makes any such failure stop the restore with nothing applied, instead of finishing with errors you might not see.
Anything created after the upgrade is lost, which is why it is worth upgrading in a quiet window and checking the result straight away. Then run the checks in Verifying afterwards again. What is not in the database dumps, and what happens to it:
  • swarmd-generated-credentials. The rollback puts the Secret back as the older release wrote it, so keys the newer version added are removed. That is safe: encryption-keys is derived from encryption-key, and the per-service Keycloak client secrets are regenerated and re-applied to Keycloak by each service at start, so upgrading again rebuilds both. The keys the older version uses are never changed.
  • ClickHouse. Its volume is kept when a rollback removes ClickHouse, so its data is still there when you upgrade again.

Skipping versions

Upgrading across several versions in one jump works — migrations are cumulative and run in order. What it costs you is the ability to tell which version broke something. On an install carrying data you care about, step through one minor version at a time and let each one settle. On a rebuildable environment, jump.

Verifying afterwards

Then run the chart’s own checks against the running install:
It checks every enabled service is healthy, Keycloak’s realm answers, service tokens carry the audience the platform requires, the gateway reports telemetry correctly, and the UI serves its sign-in page. Each failure says what is wrong, why it matters and what to do. It is read-only and safe to run at any time. Then exercise one real path — log in to the UI, or call an agent through the gateway. Pods being Running only tells you the JVMs started.

Next

Configuration

Secrets, JVM sizing, and the core/worker split.

Databases

Layouts, external Postgres and backups.