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.
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.
- Back up the data disk first. See Backup and restore. Every upgrade applies schema migrations, and migrations are one-way.
- 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.
- Shut the appliance down cleanly from your hypervisor.
- Detach the old OS disk and attach the new one in its place. Leave the data disk exactly where it is.
- 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.
- 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.
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.
Docker Compose and Kubernetes
A new compose file or a new chart version, then a restart. Take a database backup first anyway.
Docker Compose
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.
# 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
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.
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.