GoRunner docs
Search or askSearch⌘K

Update

Move to a new version with one command. Runs keep going and the address keeps answering.

5 min · Self-hosted

1.Before you update

  1. Back up the database and the files. If the update stops partway, it puts .env and the bundle’s files back as they were, but it never copies your data. See Back up and restore.
  2. Read the new release’s page in the Changelog: what changed for you, and anything to do before or after.
  3. Check the License card. With no license in force, the installation pauses as soon as the update finishes. See When a license ends.

2.Run the update

In the install folder, run deploy.sh with the new version.

Warning On v2026.10.56 or older, update to v2026.10.57 and let it finish before you go to v2026.10.58 or later. Straight across, the older containers can’t read the database until each one is replaced: the API answers 500, and workers’ saves fail and are retried.

It fetches that version’s bundle from the registry the install used, runs its check, applies the database changes, then replaces the workers and the API one at a time.

The old bundle files go to .previous/. .env and your docker-compose.override.yml are never touched. Caddy reloads in place; for a new Caddy image or changed ports it is replaced, and refuses connections for about a second. The output says which.

You should see Deployed v2026.10.30 (was v2026.10.29).

If the check finds a problem, the update stops and changes nothing. The old version keeps running. deploy.sh’s flags go past it.

What happens on Kubernetes?

Back up the database first. Give helm upgrade the new version without its v.

The migrations Job
Runs the new version’s check, then the migrations. If the check refuses, nothing is updated, and its log says why.
The app pods
Start one at a time, and take requests once ready. Nobody sees an error.
The workers
Start beside the old ones. An old worker takes no new runs, and finishes its own for up to 5½ minutes.

Check the version from inside a pod: kubectl --namespace gorunner exec deploy/gorunner-api -- wget -qO- http://127.0.0.1:3001/api/health. If the Job fails, the new pods keep waiting and the old ones keep serving: fix the cause and run helm upgrade again.

cd gorunner
./deploy.sh v2026.10.30
Docker’s output, shortened
==> Fetching the install bundle for v2026.10.30 (ghcr.io/ralve-org/gorunner-selfhost:v2026.10.30)
==> Pulling ghcr.io/ralve-org/gorunner-selfhost:v2026.10.30
…
==> Checking everything v2026.10.30 depends on, with v2026.10.30’s own check
…
Everything GoRunner needs is in place (1.8 s).
==> Applying migrations
==> Starting the new worker generation alongside the old one
==> Replacing the old worker generation
==> Retiring the rollout workers
==> Rolling the API: the twin first, while api answers
==> Rolling the API: api, while the twin answers
==> Reloading Caddy's configuration (no gap)
==> The API reports v2026.10.30

Deployed v2026.10.30 (was v2026.10.29). .env now says GORUNNER_TAG=v2026.10.30.

3.On several servers, go in order

Update the main server first, then each worker server, with the same version. See Several servers.

bash
# on the main server, then on each worker server
./deploy.sh v2026.10.30

After the update

  1. The last lines say The API reports v2026.10.30 and .env now says GORUNNER_TAG=v2026.10.30.
  2. docker compose ps: every line’s STATUS starts with Up, with (healthy) where shown.
  3. Sign in, to check the dashboard answers.
  4. In Platform › Settings › General, the License card still lists what it did, such as Embedding.

Your customers’ embeds keep working; an open one may offer a reload. New switches for customers arrive off.

How do I check what I download?

Each release’s notes name its image’s digest, sha256: and 64 characters. The Digest: line must match:

bash
docker buildx imagetools inspect \
  ghcr.io/ralve-org/gorunner-selfhost:v2026.10.30

To install exactly that image, use the digest in place of the version:

bash
docker run --rm \
  ghcr.io/ralve-org/gorunner-selfhost@sha256:<digest> \
  install | tar -x

A bundle sent as a file comes with SHA256SUMS: run sha256sum -c SHA256SUMS beside it. On Kubernetes, image.digest pins the image.

Go back to the version before

Run deploy.sh with the older version. That works while the newer version hasn’t changed the database. Once it has, the older version’s check refuses: “the database was updated by a newer GoRunner than this one”.

bash
./deploy.sh v2026.10.29

Go past that refusal with --skip-check only when the release notes of every version you go back over say that going back past their database changes is safe, and the check of the version you run now (docker compose run --rm check) reports no problem. Otherwise, the backup you took before the update is the way back. v2026.10.0 to v2026.10.2 have no such check: go back to them only with a backup.

When is going back refused?

deploy.sh refuses to go back to v2026.10.2 or older, and changes nothing, when the installation uses something those versions can’t run:

  • your own database, Redis or file storage, or no file storage;
  • several servers;
  • no mail, or SMTP over TLS from the first byte (port 465, or SMTP_SECURE=tls);
  • certificates in certs/;
  • a company proxy.

Going back to v2026.10.0 or v2026.10.1 behind your own proxy is refused too. The way back is then a backup taken before the update.

Warning Once an installation has run v2026.10.58, it can’t go back below v2026.10.57. v2026.10.58 removes database columns that older versions still read, so sign-in, organizations and workspaces fail on them and a run’s steps can’t be saved. An older version’s check may still offer --skip-check: don’t use it. The way back is the backup you took before the update.

Warning Going back from v2026.10.22 or later to an earlier version needs the OAuth rollback guard run on the database first, or an AI app could open without a click. Ask GoRunner for it before you go back.

On Kubernetes, helm rollback gorunner --namespace gorunner is safe only while the newer version hasn’t changed the database; its Job’s log says whether it did. Nothing stops it after that: the older Job’s check fails, yet its pods still start on a database they don’t fully know. Use the backup instead.

How do I apply a change to .env?

Run the update with the version you already run. It checks the new settings, then restarts what changed the same way.

bash
./deploy.sh "$(cat VERSION)"

Checked against 12d85b3b