cpk Command Reference
cpk is the installer and lifecycle binary shipped inside the CloudPeek bundle. Run commands from inside the cloudpeek/ directory: cpk resolves the compose file, image archive and supporting directories relative to its working directory, and stops immediately if it cannot find them.
uninstall is a partial exception. Its Docker cleanup works from anywhere, because it finds containers, volumes and images by label. Its second step, the offer to delete the generated secrets, only ever looks at the directory you ran it in, so running it from elsewhere silently skips that prompt. There is no reason not to be consistent and run everything from the install directory.
| Command | What it does |
|---|---|
./cpk install | Run the installer. Refuses to run over an existing install. |
./cpk configure | Update safe operational settings in place while preserving data, public identity and durable credentials. |
./cpk update --new PATH | Upgrade in-place from a newer installer tarball (-y to skip the prompt). |
./cpk adduser | Add a user from the host, interactively. |
./cpk uninstall | Remove the containers, volumes, network and images, then offer to remove the generated secrets. Destroys your data. |
./cpk export | Export the current instance (add --save-data to include volumes). |
./cpk import | Import and start a cluster from a previous export. |
./cpk verify | Run the post-install healthcheck (needs Chrome + chromedriver). Not read-only by default. |
./cpk diagnostics | Report what is wrong with a running install and write a redacted support bundle. Strictly read-only. |
./cpk renew-cert | Replace the TLS certificate and restart the proxy. |
./cpk sync-zitadel-roles | Repair the identity provider's role catalogue, when update reports its automatic sync did not run. |
./cpk migration --last-version VERSION | Apply the one-time reconciliation steps introduced since VERSION. Normally run for you by update. |
./cpk --help (-h) | Show full usage help. |
./cpk --version (-v) | Show the installed version. |
./cpk --verbose | Detailed logging. |
Command-specific flags
| Flag | Applies to | What it does |
|---|---|---|
--force | install | Install even if this directory already holds an install. Breaks the existing instance. |
--new PATH | update | The newer installer tarball to upgrade from. Required. A relative path is resolved against the current directory. |
-y, --yes | update, configure | Skip the ordinary final confirmation. Configure still asks its settings questions, and aborts rather than continuing if a dependency is unreachable. |
--save-data | export | Include the data volumes in the export. Stops the containers for the duration. |
--keep-rate-limit | verify | Leave .secrets/api.env and the API container untouched. Use on production installs. |
--regenerate | verify | Rebuild .secrets/tests.env from api.env. |
--cert PATH | renew-cert | The replacement certificate, PEM. Prompts if omitted. |
--key PATH | renew-cert | The replacement private key, PEM. Prompts if omitted. |
--last-version VERSION | migration | The version the install was on before the update. Required, and validated, so a typo gets a one-line error rather than a stack trace. |
--http-proxy URL | install | Outbound HTTP proxy. Also settable as http_proxy/HTTP_PROXY; the flag wins. |
--https-proxy URL | install | Outbound HTTPS proxy. Also settable as https_proxy/HTTPS_PROXY. |
--no-proxy-extra LIST | install | Comma-separated hosts to add to the proxy bypass list. Additive: it never shrinks the built-in list. |
--ca-cert PATH | install | Corporate CA bundle to trust. Must be a readable file, or the install fails. |
--since DURATION | diagnostics | Log window, e.g. 30m, 6h, 2d. Default 24h, maximum 48h. |
--max-log-lines N | diagnostics | Cap log collection per container. Default 100000. |
--output-dir DIR | diagnostics | Where to write the bundle. Default ./cloudpeek_<hostname>_<ddmmyy_hhmm>. Must be empty or new. |
--no-bundle | diagnostics | Report on screen only, writing nothing to disk. |
--no-archive | diagnostics | Leave the bundle directory untarred. |
--verbose raises the log level globally. configure emits value-free validation and health milestones; install, update, import, migration and sync-zitadel-roles provide their command-specific diagnostics. It has no effect on uninstall, export, adduser or verify. diagnostics uses it to also show the checks that passed, not just the problems.
Flags are parsed from one shared table, so any flag is accepted on any command and simply ignored where it does not apply: ./cpk uninstall --cert foo runs an ordinary uninstall. An unrecognised flag is a different matter and fails the parse before anything runs.
Docker requirements
Most commands check for Docker before doing anything, and require Docker Engine 29 or newer. adduser, verify and sync-zitadel-roles skip that check deliberately, because they talk to an already-running stack rather than managing it.
diagnostics skips it for a different reason. It does need Docker, but the standard check refuses to run on a daemon below the minimum, and diagnostics has to work on hosts that are already broken. So it runs a softer preflight of its own: an unsupported daemon is reported as a finding and the run continues. It stops only when the docker binary is missing or the daemon cannot be reached at all.
What each command asks before it acts
Several commands are interactive, and a couple ask a second question well after the one you were expecting. This is the full list of confirmation points.
| Command | Prompt |
|---|---|
install | Host, scheme, TLS source, admin account and per-service settings. |
configure | Per settings group, then a final preview and Apply these changes?. |
update | A single Continue? warning, skipped by -y. |
uninstall | Continue?, then, after the Docker cleanup, Also remove the generated secrets?. |
import | Restore volume data?, but only when the export contains volume archives. |
verify | Nothing, unless no default AI provider is configured, in which case it asks for one. |
diagnostics | Nothing. It never prompts and never changes the install. |
renew-cert | Certificate and key paths, unless both were passed as flags. |
adduser | Email, password, names and permissions. See below. |
uninstall asks twice. The first prompt covers containers, volumes, the network and images. The second, which appears only after that work is done, offers to delete the generated secrets (compose.env, api.env, worker.env, frontend.env, tests.env and the Zitadel master key). Declining leaves them in place, which will make the next ./cpk install refuse to run unless you pass --force. Operator-supplied certificates in .secrets/tls are never deleted either way.
./cpk verify is not read-only. By default it writes RATE_LIMIT__ENABLED=false and CLOUDPEEK_E2E_FLAGS=1 into .secrets/api.env and recreates the API container, restoring the file when it finishes. The test suite's request bursts would otherwise trip the rate limiter. On a production install, pass --keep-rate-limit so nothing is touched, accepting that the feature-flag scenarios will fail unless CLOUDPEEK_E2E_FLAGS=1 is already set.
Collecting a support bundle
./cpk diagnostics is what to run when something is wrong and you want CloudPeek support to look at it. It inspects the running stack, prints what it finds, and writes a bundle you can send on.
cd cloudpeek
./cpk diagnostics
It is strictly read-only. It never starts, stops or reconfigures anything, never prompts, and writes nothing outside the output directory. It is safe to run on a production install, and safe to run repeatedly.
It also works on a broken one, which is rather the point. If the stack is completely down, the run still completes and still produces a bundle: it falls back from the compose configuration to Docker labels to container name patterns, and reports each missing piece as a finding.
What it checks
Nine checks run in order, each reporting its own findings:
| Check | Looks at |
|---|---|
| Host information | Kernel, Docker version and storage driver, disk and memory |
| Configuration keys | Which expected keys are present in .secrets/*.env, by name |
| Container state | Status, restart counts, exit codes, out-of-memory kills, health |
| Expected services | Services declared in compose that have no container, or the wrong state |
| Version drift | Whether each running image matches the installed cpk version |
| TLS | Certificate subject, validity dates and expiry warnings |
| Container logs | Error lines in the log window, grouped by frequency |
| Service health | API, frontend and MCP health endpoints, probed from inside the network |
| Dependencies | Redis, Postgres, ChromaDB and Neo4j reachability, plus queue depths |
Problems are printed as you go, then summarised: either Diagnostics found no problems. or Diagnostics found N error(s) and M warning(s). Add --verbose to see the passing checks too.
What is in the bundle, and what is redacted
Everything written to the bundle, and everything printed to the terminal, passes through a single redaction filter. It masks credential-shaped text: passwords embedded in connection strings, environment variables and JSON fields whose name looks secret (PASSWORD, SECRET, TOKEN, API_KEY, _PAT and similar), secrets in URL query strings including AWS presigned parameters, and Authorization: Bearer/Basic values.
Three things are worth stating plainly:
- Your TLS private key cannot appear in a bundle. The certificate check reads only
cert.pem, to report its subject and dates.key.pemis never opened. - The values in
.secrets/*.envare never collected. The configuration check works purely from key names, so it can tell you a key is missing without ever reading what it is set to. - No file is copied verbatim.
.secrets/,compose.ymland Docker's own configuration are never included. The bundle contains only the command output described above.
Redaction masks credentials, not content. Application logs can legitimately contain incident data, hostnames, IP addresses, user email addresses and model payloads, and none of that is masked. The command says so when it finishes, and it is worth acting on: review a bundle before you send it. If it contains something you cannot share, delete that file from the bundle directory and re-archive it, or re-run with --no-bundle and share only the on-screen summary.
Masking is also applied line by line, so a credential split across two lines is not caught.
Narrowing what it collects
./cpk diagnostics --since 2h --max-log-lines 5000
--since accepts 30m, 6h, 2d and so on, defaulting to 24h and capped at 48h. An invalid or zero value is rejected before anything is collected. Narrowing the window is the usual way to keep a bundle small when you already know roughly when the problem started.
Use --no-bundle to see the findings without writing anything to disk, and --no-archive to leave the bundle as a directory rather than a .tar.gz when you want to inspect or edit it first.
Sending it
By default the bundle lands in ./cloudpeek_<host>_<timestamp>/ and is archived alongside it as .tar.gz. Send that archive to your CloudPeek support contact.
--output-dir must point at a new or empty directory. This is deliberate: the bundle is archived whole, so an existing directory would sweep unrelated files into something you are about to email.
Exit codes
Most commands exit 0 on success and 1 on failure. Three behaviours are worth knowing before you put cpk in a script.
verify never returns a non-zero exit code. It catches everything, and a failing suite is reported as a warning rather than an error. Do not gate a pipeline on its exit status; read its output instead.
diagnostics findings never change the exit code either. It exits 0 even when it reports errors, on the same reasoning: finding problems is the job, not a failure to do it. It exits 1 only for an invalid flag value, a missing docker binary or an unreachable Docker daemon. If it cannot write the bundle, it warns and still exits 0.
update fails closed when it cannot ask. Without -y, its confirmation prompt aborts rather than hanging if there is nothing on standard input, so an unattended run that forgets -y stops safely instead of blocking forever.
Recovering a partial update
update runs two follow-up steps that are allowed to fail without failing the upgrade itself, because neither affects whether the new version runs. If either warns, run the command it names.
Warning from update | Fix |
|---|---|
| The Zitadel role sync did not run | ./cpk sync-zitadel-roles |
| The migration step did not run | ./cpk migration --last-version VERSION, with the version it prints |
Both are safe to re-run. migration applies only the steps introduced between the version you give it and the installed version, so running it twice does nothing the second time, and running it with a version at or above the current one reports that there is nothing to do.
Where each command is covered
install— Installing CloudPeekconfigure— Installing CloudPeek, under Reconfiguring an existing installupdate,migrationandsync-zitadel-roles— Updating CloudPeekexportandimport— Export and Importuninstall— Uninstalling CloudPeekrenew-cert— Installing CloudPeek, under Rotating the certificateverify— Installing CloudPeek, under Optional: verify the installdiagnostics— Collecting a support bundle, above
adduser creates an account from the host, without going through the web interface. It is the quickest way to add the second account to a fresh instance; day to day, manage users in the app instead — see Admin & Settings.
It asks, in order: email, password and confirmation (same complexity rules as the installer, and the same abort on a mismatch), first name and last name (both defaulting to User), then Grant all permissions to this user? y/n. Answering y is the quick path. Anything else walks through each resource in turn, offering all, none or pick, where pick asks per action — thorough, but long.
If the account is created but the permissions cannot be granted, adduser deletes the new user rather than leaving one behind with no access. In the rare case that the cleanup also fails, it prints the user id and email to remove by hand before retrying.
It needs .secrets/api.env and .secrets/compose.env, so it only works on a host where the install has already run.
Related
- Prerequisites: what the host needs before you start.
- Installing CloudPeek: the full install walkthrough.
- Uninstalling CloudPeek: what
uninstalldeletes.