Skip to content

Upgrade and Rollback

Upgrade Containment Chamber with minimal downtime and a safe rollback path

Containment Chamber ships as a single static binary or Docker image. Upgrades normally replace the binary/image and restart the process. SQL anti-slashing backends initialize missing tables on startup; DynamoDB tables must already exist and row-format changes are versioned in the data model.

  1. Check the changelog for breaking changes, especially storage-format, config, auth, or seal-state changes.
  2. Back up your current binary or record the exact Docker/Helm image tag you’re running.
  3. Back up anti-slashing state:
    • PostgreSQL: take a pg_dump or provider snapshot.
    • SQLite: stop the signer, then copy the SQLite file.
    • DynamoDB: enable point-in-time recovery or take an on-demand backup of the anti-slashing table.
  4. For DynamoDB-backed deployments, also back up the validator-key table and signer-state table.
  5. Save the current config and root/operator tokens needed to inspect the upgraded signer after restart.
Terminal window
# Stop the service
sudo systemctl stop containment-chamber
# Download new binary
curl -L -o containment-chamber \
https://github.com/unforeseen-consequences/containment-chamber/releases/latest/download/containment-chamber-linux-amd64
chmod +x containment-chamber
# Keep the old binary for rollback
sudo cp /usr/local/bin/containment-chamber /usr/local/bin/containment-chamber.bak
# Install the new binary
sudo install -m 755 containment-chamber /usr/local/bin/
# Restart
sudo systemctl start containment-chamber
sudo systemctl status containment-chamber

Stop the service, replace the binary, and restart.

Current release artifacts publish containment-chamber-linux-amd64. Check the release notes before assuming another architecture is available.

After restarting, confirm the signer is healthy:

Terminal window
curl http://localhost:9000/upcheck
curl http://localhost:9000/healthcheck
curl http://localhost:9000/api/v1/eth2/publicKeys

For state-backed deployments, also confirm the seal state:

Terminal window
containment-chamber operator status \
--auth-token env:CC_AUTH_TOKEN \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

Containment Chamber has a 25-second graceful shutdown drain. When the process receives SIGTERM, it stops accepting new connections but finishes all in-flight signing requests before exiting. This means brief upgrades with a single instance won’t lose requests that are already being processed.

For true zero-downtime, run multiple instances behind a load balancer:

  1. Configure your load balancer or orchestrator readiness check to use /healthcheck, not /upcheck.
  2. Start the new instance and wait for it to pass health checks.
  3. Stop the old instance. The 25-second drain ensures in-flight requests complete.
  4. Remove the old instance from the load balancer pool.

/upcheck is liveness only. It returns 200 while the process is alive, including while the signer is sealed. /healthcheck returns ready only after a signer is present and the anti-slashing backend health poller succeeds.

If something goes wrong after upgrading, first check the changelog for storage-format changes. Rolling back the binary is usually enough for config or runtime issues, but storage-format changes may require restoring the matching database or DynamoDB table backup.

Terminal window
sudo systemctl stop containment-chamber
sudo mv /usr/local/bin/containment-chamber.bak /usr/local/bin/containment-chamber
sudo systemctl start containment-chamber

After rollback, check /healthcheck, confirm the seal state, and verify validator clients reconnect before considering the incident closed.