Upgrading

How to upgrade your self-hosted KubeWatch installation to a newer version.

KubeWatch follows semantic versioning. Minor and patch releases are safe to apply directly. Major version upgrades may include a database migration, check the release notes first.

License renewal

A self-hosted license is an annual subscription: every update and security patch is included for the life of the subscription, and renewing at the end of the year (same price, same self-hosted pricing page) simply extends your existing key another year, nothing to re-activate. Settings → Billing → License shows the date your license runs through. Your instance re-checks its license against the license server every 24 hours; if it lapses without being renewed, that check starts failing and access pauses until you renew, so don't let it run out unnoticed.

The installer ships every service pinned to the latest tag, so the simplest and safest upgrade path is the System Update page in the dashboard (Admin section) as an admin: click Update Now. It pulls the latest images, refreshes and applies the database migrations bundle, then recreates the stack, in that order, so migrations always land before the new images start serving traffic. It requires /var/run/docker.sock to be mounted into the platform (already the case for installs via install.sh).

Manual upgrade (Docker Compose CLI)

If you'd rather drive it from the CLI, or Update Now isn't available in your setup:

cd ~/kubewatch-erp

# 1. Refresh the database migrations bundle
curl -fsSL https://raw.githubusercontent.com/lloyd-theophilus/kubewatch-releases/main/migrations.tar.gz -o migrations.tar.gz
tar -xzf migrations.tar.gz -C migrations

# 2. Pull the latest images
docker compose pull

# 3. Apply any new migrations before anything else restarts
docker compose run --rm migrate

# 4. Recreate services with the new images
docker compose up -d

Services that haven't changed will not be restarted.

The `migrations` folder is only ever downloaded once, at install time. Skipping step 1 means new tables or columns added since your install won't exist yet, which shows up as pages reporting no data or `500` errors from routes that depend on them.

Check current versions

The installer doesn't pin services to a version tag by default (every image is latest), so docker compose images won't show a meaningful version number unless you've pinned one yourself (see below). To check what's actually running, open Settings → System Update in the dashboard: it reports the running version (from the APP_VERSION environment variable, stamped at install time) and whether a newer one is available.

Database migrations

Migrations run via a dedicated one-shot migrate service (not automatically inside each service's own startup): it applies every SQL file under ./migrations and then exits. docker compose up -d alone does not re-run it once it has already completed successfully, which is why the manual path above calls docker compose run --rm migrate explicitly after refreshing the bundle. If a migration fails, check its logs:

docker compose logs migrate

Pinning to a specific version

To prevent automatic upgrades to the latest tag, pin each service to a specific version in docker-compose.yml:

services:
  gateway:
    image: ghcr.io/lloyd-theophilus/kubewatch-gateway:1.4.2

Then upgrade by changing the version numbers and running the manual steps above (pinned installs should always use the manual path, since the in-app updater always pulls latest).

Rollback procedure

If an upgrade causes issues:

cd ~/kubewatch-erp

# 1. Stop current services
docker compose down

# 2. Pin the image tags in docker-compose.yml to the previous version
#    (edit each "image:" line, e.g. kubewatch-gateway:latest -> kubewatch-gateway:PREVIOUS_VERSION)

# 3. Recreate the services with the pinned images
docker compose up -d
Rolling back after a database migration has run may leave the database in an incompatible state. Always [back up your data](/self-hosted/backup-restore) before upgrading.

Upgrade checklist

Before upgrading:

  • Read the release notes for any breaking changes
  • Back up your database (docker compose exec postgres pg_dump ...)
  • Take a VM snapshot if running on a cloud VM
  • Schedule the upgrade during a low-traffic window
  • Verify all agents are connected and reporting before upgrading