Operations

Upgrading

On the appliance an upgrade is a disk swap: new OS disk, same data disk. On Compose it is a new compose file and a restart — the images in yours are pinned, so a pull alone changes nothing. On Kubernetes it is a new chart version. Schema migrations run automatically in all three. Taking a release is also how you patch the appliance's operating system — section 03.

01

The appliance — swap the OS disk

Your database, artifacts, install identity, secrets and license all live on disk 2, so an upgrade never touches them.

Before OS disk 0.4.2 disposable Data disk your install detach and keep never detached, never reformatted kept until the new one is proven After OS disk 0.4.3 from the new release Data disk same one, untouched Your database, artifacts, install identity, secrets and license live on disk 2 — so they survive the swap, and the licence seat is not consumed again.
Diagram — the appliance upgrade. The data disk is never part of what an upgrade replaces.
  1. Back up the data disk first. See Backup and restore. Every upgrade applies schema migrations, and migrations are one-way.
  2. Download and unpack the new release's disks exactly as you did for the install. You only need the new OS disk — discard the new release's data disk, it is an empty one.
  3. Shut the appliance down cleanly from your hypervisor.
  4. Detach the old OS disk and attach the new one in its place. Leave the data disk exactly where it is.
  5. Power on. The appliance recognises an install that has already been sealed, leaves its identity alone, applies any new migrations, and comes back up on the new version. Your license, install ID and stored secrets are untouched.
  6. Keep the old OS disk until you are satisfied. Rolling back is re-attaching it — provided you have not since applied a schema migration, which is why step 1 is step 1.
Never Do not replace, reformat or "start clean with" the data disk. It carries the only copy of this install's secret-protection key; without it, stored project secrets cannot be decrypted by anything, ever.

Check the portal's Releases tab before every upgrade — it carries the per-release "before upgrading" notes, and your own admin console reads the same feed and tells you when you are behind.

02

Docker Compose and Kubernetes

A new compose file or a new chart version, then a restart. Take a database backup first anyway.

Docker Compose

A pull is not an upgrade The bundle you installed from is pinned: every image reference in its docker-compose.yml names an exact version. That is what makes an install reproducible, and it is also why docker compose pull on its own can never upgrade you — it re-pulls the same tags. An upgrade is: new compose file, same .env, pull, up.
shell
# 1. in your download directory: verify the new bundle, unpack it somewhere
#    that is NOT your live install
sha256sum -c SHA256SUMS
unzip testvibe-selfhosted-v0.4.7.zip -d /tmp/testvibe-0.4.7

# 2. copy ONLY docker-compose.yml across — your .env stays exactly as it is
cd /opt/testvibe
cp /tmp/testvibe-0.4.7/docker-compose.yml ./docker-compose.yml
diff .env /tmp/testvibe-0.4.7/.env.example | grep '^>' || true

# 3. the images are private, so authenticate first
docker login testvibe.azurecr.io
docker compose pull
docker compose up -d
docker compose ps

Your .env is where all of your configuration and every secret lives — never overwrite it. The diff in step 2 is worth reading: a release that adds a required variable adds it to .env.example, and the stack refuses to start without it rather than starting misconfigured. The schema job re-runs and applies only what is new (DbUp skips what is already applied); data lives in the named volumes and is untouched. Take a database backup first anyway.

Your own admin console prints this same sequence under Updates, filled in for the version you are on and the version you are going to.

Kubernetes

shell
helm upgrade testvibe oci://testvibe.azurecr.io/charts/testvibe \
  --namespace testvibe --version 0.4.7 --reuse-values

The migrations Job runs alongside the release, and each app Deployment carries a wait-for-schema init container that blocks until the schema is current — so the new app version does not start against a half-applied schema. Pass secrets.protectionKey again if your install has an explicit one: Helm does not remember it, and an upgrade that omits it blanks the value.

03

Patching the operating system

On the appliance you patch the OS by taking the next appliance release. There is no other route, and that is deliberate.

  • The OS disk is the unit of patching. Each release is built from a fresh Ubuntu 24.04 LTS base with current security updates, plus the pinned runtimes and browsers the product needs. Taking a release is taking the patches — the same disk swap as section 01, and the data disk is not part of it.
  • There is no login, so there is no apt upgrade. The appliance ships no account you can sign in as. This is what makes the image reproducible and what stops a fleet of appliances from drifting apart.
  • Do not try to patch it in place even if you find a way. The browser and runtime versions are pinned against each other; an out-of-band upgrade of either is how you get a runner that cannot find a browser.
  • Watch the release feed. Your admin console's Updates panel reads the same list as the portal's Releases tab and tells you when a newer release exists. It does not update itself — applying an update restarts services, and the console runs beside an application that executes generated test code, so it deliberately holds no privilege to do that.
  • If you need a faster patch cadence than releases give you, run the Docker Compose or Kubernetes shape instead: there you patch the host or the nodes yourself on your own schedule, and only the TestVibe images come from us.