Upgrading
Containment Chamber ships as a single static binary (or Docker image) with no runtime dependencies. Upgrades replace the binary and restart the process. Schema migrations run automatically on startup.
Before You Upgrade
Section titled “Before You Upgrade”- Check the changelog for breaking changes.
- Back up your current binary or note the Docker image tag you’re running.
- Verify your anti-slashing database is backed up (PostgreSQL
pg_dumpor copy the SQLite file).
Upgrade Steps
Section titled “Upgrade Steps”Stop the service, replace the binary, and restart:
# Stop the servicesudo systemctl stop containment-chamber
# Download new binarycurl -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 rollbacksudo cp /usr/local/bin/containment-chamber /usr/local/bin/containment-chamber.bak
# Install the new binarysudo install -m 755 containment-chamber /usr/local/bin/
# Restartsudo systemctl start containment-chambersudo systemctl status containment-chamberBinaries are available for linux-amd64 and linux-arm64. Adjust the download URL accordingly.
Pull the new image and recreate the container:
# Docker Compose (recommended)docker compose pull && docker compose up -dOr with standalone docker run:
docker pull ghcr.io/unforeseen-consequences/containment-chamber:latestdocker stop containment-chamberdocker rm containment-chamberdocker run -d --name containment-chamber \ -p 9000:9000 -p 3000:3000 \ -v ./config.yaml:/config.yaml:ro \ -v ./keystores:/keystores:ro \ ghcr.io/unforeseen-consequences/containment-chamber:latest \ -c /config.yamlAfter restarting, confirm the signer is healthy:
curl http://localhost:9000/upcheckcurl http://localhost:9000/api/v1/eth2/publicKeysZero-Downtime Upgrades
Section titled “Zero-Downtime Upgrades”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:
- Configure your load balancer to health-check
/upcheck. - Start the new instance and wait for it to pass health checks.
- Stop the old instance. The 25-second drain ensures in-flight requests complete.
- Remove the old instance from the load balancer pool.
Rollback
Section titled “Rollback”If something goes wrong after upgrading, restore the previous version:
sudo systemctl stop containment-chambersudo mv /usr/local/bin/containment-chamber.bak /usr/local/bin/containment-chambersudo systemctl start containment-chamber# Roll back to a specific versiondocker compose down# Update image tag in docker-compose.yml to the previous versiondocker compose up -dOr pull the previous tag directly:
docker pull ghcr.io/unforeseen-consequences/containment-chamber:v1.1.0Schema migrations are backward-compatible, so rolling back to a previous binary version won’t cause database issues.