Upgrades and worker updates
Upgrade the control plane safely, rotate ENCRYPTION_KEY, and publish signed worker releases that workers install and roll back by themselves.
Self-hosted
Upgrade the control plane
- Back up MongoDB and your
.env, includingENCRYPTION_KEY. - Pull the new version and rebuild:
docker compose up -d --build, or repeat the Node.js build steps. - Indexes and data migrations run automatically at startup, under a lock.
Workers keep running during the upgrade: they buffer events and retry state changes until the control plane is back. Read the release notes for breaking changes and migration notes before upgrading.
Rotate ENCRYPTION_KEY
- Generate a new key:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))". - Set
ENCRYPTION_KEYto the new key andENCRYPTION_KEYS_PREVIOUSto the old one; restart. The control plane reads secrets with the old key and re-encrypts them in the background. - Confirm:
docker compose exec control-plane node apps/api/dist/main.js reencrypt-secrets. Exit code 0 means every secret uses the new key; exit code 2 lists secrets no configured key can decrypt. - Remove
ENCRYPTION_KEYS_PREVIOUSand restart.
Publish worker releases
The control plane hosts updates for its workers. Releases are signed offline, so a compromised server cannot push code to workers.
- Once, on a machine you trust:
node scripts/sign-release.mjs keygen release-2026. Keep the private key offline; giverelease-2026.public.pemto your workers (worker UI → Updates → Trusted release keys). - Build the package:
node scripts/package-worker.mjs --tarball. - Dashboard → Server → Worker releases: choose channel and version, upload the package. The page shows the exact signing command.
- Sign on the trusted machine (
node scripts/sign-release.mjs sign … > manifest.json) and uploadmanifest.json. The server checks that it describes the uploaded package.
Workers with automatic updates install it within six hours; others show it under Updates. See Worker updates for switching and rollback.