cb — Command-Line Tool
cb is the management CLI for Circuit Breaker. One implementation ships for every
supported install mode. It reads a versioned install identity record
(install-identity.json) written by the installer, then dispatches to
mode-aware status, diagnosis, backup, and lifecycle commands.
Machine-readable mode details live in
specs/install/compatibility-matrix.yaml.
Installation
Every first-class installer installs the same CLI to /usr/local/bin/cb:
| Install method | How cb is installed |
|---|---|
Native (install.sh) |
Automatic — copies the canonical CLI during setup stage 9 |
Mono / Docker Compose (install.sh --docker) |
Automatic when run from a checkout that contains cb; otherwise sudo install -Dm755 ./cb /usr/local/bin/cb |
| Proxmox LXC | Same as native inside the CT |
| Distro packages (advanced) | Ships /usr/local/bin/cb via nfpm.yaml |
Running cb with no arguments (or cb help) prints the command list.
Install identity
After install, run:
cb info
cb info --json
Identity search order (no guessing of container names or ports):
$CB_IDENTITY_PATH(if set, this path alone — fail closed when missing)/etc/circuitbreaker/install-identity.json(native / Proxmox)/etc/circuit-breaker/install-identity.json(packages)$CB_DATA_DIR/install-identity.json(mono data volume)~/.circuit-breaker/install-identity.json(Compose host)
A missing or malformed identity is a diagnosis failure. Legacy
~/.circuit-breaker/install.conf / /etc/circuit-breaker/install.conf remains a
one-release compatibility hint; cb info and cb doctor tell you to migrate by
re-running the installer.
Schema: specs/install/identity.schema.json.
Command availability by install mode
| Command | Native | Mono (Docker/Compose) | Package (advanced) |
|---|---|---|---|
info, status, resources, doctor, diag bundle, setup, setup-token, logs, restart, backup, restore, config validate, version, uninstall |
✅ | ✅ | ✅ |
migrate, token, user, agent |
✅ | ✅ | ✅ |
update |
✅ (via installer guidance) | ✅ | ✅ |
vault-recover |
✅ | ✅ | ✅ |
migrate, token, user and agent are the headless administration commands
(SRV-06). They need a reachable database.
Unsupported operations fail with the detected mode, why the operation is unavailable, and the supported alternative.
Configuration
Prefer install identity. Paths, container names, compose files, and health URLs come from that record.
On native/Proxmox installs the CLI also sources /etc/circuitbreaker/.env so
admin commands see the same environment as the units.
On package installs the env file is /etc/circuit-breaker/circuit-breaker.env
(also recorded in identity).
First-run setup
cb setup # pending vs complete (bootstrap status)
cb setup-token # print the one-time token once (never paste into doctor/logs)
Backend bootstrap status (needs_bootstrap) is authoritative. The mono image
no longer writes .oobe-complete before account creation.
Diagnosis
cb doctor
cb doctor --json
Human output is concise; --json emits an array matching
specs/install/diagnostic-result.schema.json.
Evidence is bounded and redacted (no vault keys, JWTs, or passwords).
To include application-layer checks from the authenticated admin API, set a bearer token and re-run:
export CB_ADMIN_TOKEN="<admin API token>"
cb doctor --json
When CB_ADMIN_TOKEN is unset, doctor adds a diagnostics/admin row with status
skipped and does not call the API. Never put the token value in logs or support
bundles.
Authenticated detail is also available directly:
GET /api/v1/admin/diagnostics
Public probes (/livez, /startupz, /readyz, /health) are unchanged —
liveness stays process-only; readiness stays dependency-aware.
Troubleshooting tree (doctor component)
component / result |
What to do |
|---|---|
identity fail |
Re-run the installer for your mode; then cb info |
docker / container fail |
Start Docker / cb restart |
postgres fail |
Check DB process/credentials; fix top-down |
redis warn |
Optional for inventory; restore Redis for pub/sub |
backend fail |
Inspect logs: cb logs |
storage warn |
Free space under 1 GiB — prune backups or grow volume |
workers fail/warn |
Restart workers; check *.healthy under the data dir |
cb diag bundle
cb diag bundle [--output <path>]
Collects install.log, cb doctor --json, the circuit-breaker --selftest
output, unit status, journal output, the install identity, and the redacted
env file into one .tar.gz — one file to attach to an issue instead of
copy-pasting several. Every file it collects has, at some point, held a JWT
secret, a Fernet vault key, or a database password, so every source is passed
through the same redaction that already masks secrets and connection-string
credentials, with no truncation — a 500-line log stays a 500-line log, fully
redacted, not a 500-character fragment.
It fails closed: without python3 on PATH it refuses to produce a bundle at
all and exits non-zero, rather than ship anything unredacted. It never uploads
anything — it writes the archive and prints its path; where that file goes
from there is up to you.
Common commands
cb status
Show container or systemd unit status for the active mode.
cb resources
Measure Circuit Breaker’s local resource footprint, including its API, workers, and dedicated dependencies. Works without a running backend or database and does not read the app’s secrets, change resource limits, or enable accounting.
cb resources # snapshot over 2 seconds
cb resources --watch # live view; q or Ctrl-C exits
cb resources --watch --interval 5 # refresh/sample interval, minimum 1 second
cb resources --json # one JSON document
cb resources --watch --json # JSON Lines for scripts
Native/Proxmox and package installs use verified systemd service cgroups. Native
PostgreSQL and cb-helperd are included even though they sit outside the app slice.
The system nginx service is shown separately as shared usage. Docker/Compose uses
the exact container in install identity and honors the selected Docker context;
capacity figures come from that daemon’s host/VM, including for remote contexts.
Inside the mono container, visible cgroup v2 counters can be read without a Docker
socket; use the host command if the container’s accounting boundary is hidden.
CPU is measured in cores consumed (1.00 = one busy logical CPU). Memory is charged
memory including cache, with cache and swap also shown separately; this differs
from Docker CLI’s cache-subtracted display. I/O values are rates over the actual
sample interval. JSON preserves cumulative counters, per-metric sources and missing
value reasons, scope-specific limits, and coverage notices (schema_version: 1).
Missing counters are null, and incomplete totals are labeled observed subtotals.
Live terminal controls: c sorts by CPU, m by memory, e expands workers, and
j/k scroll through component details, limits, and coverage notices.
Redirected output has timestamped snapshots without terminal control codes.
Collection rechecks membership and resets rate baselines after restarts or counter
resets. Limits apply to their named service/slice/container, not necessarily the
whole application; visible host/guest capacity may exceed an enclosing quota.
Coverage depends on the installation:
- Native network rates require existing systemd IP accounting. Host networking or shared Docker network namespaces cannot supply app-only network rates.
- Native totals sum verified service cgroups; residual charges directly on parent slices are not assigned to the app. The optional Docker proxy includes its launcher and verified container on the local system daemon; an unreadable local Docker socket produces an explicit gap and partial totals.
- Shared host services, external databases, remote agents, browser usage, and jobs
launched outside managed app services are outside app totals. Package installs
include the dedicated
circuit-breaker-natsservice when present, but cannot attribute a shared system database to this app. - Mono currently reports container totals. Internal process breakdowns and the optional disk footprint scan are follow-up features, not current flags.
Requires Python 3.9+ (the bundled interpreter is preferred). The host Docker path
also requires the Docker CLI and access to its daemon; native needs access to
systemd and readable accounting counters. An unreadable identity needs an account
with permission to read it, rather than a reinstall. A missing/invalid identity
must be repaired; resource accounting does not guess from legacy install.conf.
Exit status: 0 for a usable report, including explicitly partial reports; 1
when installation scope/runtime cannot be collected; 2 for invalid arguments.
cb doctor [--json]
Top-down health checks with remediation. Exit non-zero when any check fails.
cb logs [-f]
Tail application logs (docker logs or journalctl).
cb restart
Restart the mono container, compose stack, package unit, or native target.
cb update
Pull/recreate for mono; native/package point at the installer or package manager.
cb backup / cb restore
Full-state snapshot and restore. See Backup & Restore.
cb restore takes a snapshot tarball (cb-snapshot-*.tar.gz[.age]) only. A bare
pre-upgrade-*.sql (or .sql.gz) from install.sh --upgrade is a different
shape — database only, the upgrade rollback artifact — and is restored with
deploy/scripts/restore.sh directly, not through cb restore.
cb uninstall
Remove the installation for the detected mode.
Air-gap / offline
With CB_AIRGAP=true the application does not make outbound calls. Install and
upgrade using local bundles or package files. cb doctor still works offline
against local services; image pulls and remote installer curls will fail as
expected — use artifacts already on the host.
