CLI
The CLI is a thin client over the server API; it does not talk to Docker directly, so a server must be running.
KAIO_ADDR (default 127.0.0.1:8080) says which server it talks to. Point it
elsewhere for one command with KAIO_ADDR=10.0.0.2:8080 kaio-cli status, or
reach a node of the cluster with node <name> run.
In a development checkout, replace kaio-cli below with
cargo run --bin kaio-cli -- or make cli ARGS="…".
Global flags
Section titled “Global flags”| Flag | Effect |
|---|---|
--json |
Emit machine-readable JSON instead of formatted tables |
--version |
Print the CLI’s version and build SHA, then exit, without reaching the server |
General
Section titled “General”kaio-cli status # system summarykaio-cli health # health checkkaio-cli version # this CLI's version, and the server'skaio-cli events # recent historykaio-cli events --follow # live SSE tailkaio-cli tui # launch the interactive TUIversion prints the CLI’s own version first, with the git SHA it was built
from in parentheses, then asks the server for its own, so a CLI left behind
after an upgrade shows up as two numbers that disagree:
cli: 0.3.7 (2664602)server: 0.3.7The server line reads unreachable at <addr> when nothing answers there, and
version --json reports that as "server": null, with the SHA on its own
sha field. A build made outside a git checkout, and without KAIO_GIT_SHA
set, stamps dev instead of a SHA.
Containers
Section titled “Containers”kaio-cli container lskaio-cli container start <id>kaio-cli container stop <id>kaio-cli container restart <id>kaio-cli container pause <id>kaio-cli container unpause <id>kaio-cli container rm <id>kaio-cli container logs <id> [--follow] [--tail <n>]kaio-cli container shell <id> # interactive shell, Ctrl-] to exitStacks
Section titled “Stacks”kaio-cli stack lskaio-cli stack show <name>kaio-cli stack deploy <name> <compose_file> [--env-file .env]kaio-cli stack rm <name>kaio-cli stack start <name>kaio-cli stack pause <name>kaio-cli stack unpause <name>kaio-cli stack update <name>kaio-cli stack restart <name>kaio-cli stack logs <name> [--follow] [--tail <n>]kaio-cli stack scan <name> # Trivy vulnerability scankaio-cli stack check-update <name>kaio-cli stack versions <name>kaio-cli stack rollback <name> <version>kaio-cli stack version-rm <name> <version>Copying a stack to another server
Section titled “Copying a stack to another server”kaio-cli stack copy <name> --to prod-02 # definition only, not startedkaio-cli stack copy <name> --to prod-02 --with-volumes # carry the data acrosskaio-cli stack copy <name> --as web-staging # clone it here under another namekaio-cli stack copy <name> --to prod-02 --dry-run # show the plan, change nothingkaio-cli stack copy <name> --as web-02 --publish 8091:9091 --startkaio-cli stack copy <name> --as web-03 --port-offset 2000 --startkaio-cli stack copy <name> --as web-02 --env SITE_URL=https://staging.example.netkaio-cli stack copy <name> --as web-02 --env-file staging.envA clone on the same host claims the ports its source already holds, so the copy
is refused rather than written unusable (--allow-port-clash accepts it anyway). --publish old:new (repeatable) and --port-offset N
rewrite only the ports: entries of the copy’s compose file; --env and
--env-file override its variables. A port written as ${HTTP_PORT}:80 is left
to the variables.
The source is never stopped, written to or removed, and a copy that fails part
way is undone on the destination. --to and --from name nodes as
kaio-cli node ls does; leaving one out means this server, so a copy that stays
here needs a different name with --as.
Without --start the copy is written but not brought up: two live copies would
contend for the same DNS, webhooks, queues and mail. --allow-binds accepts
that mounted host paths stay behind, and --allow-anonymous-volumes accepts
losing volumes Docker named itself. Both are refusals by default, because
either one silently produces a copy that looks healthy and is missing data.
See the API route for what the plan contains and what stops a copy before it starts.
Stack environment
Section titled “Stack environment”Saved as pending until stack apply. See
Environment variables.
kaio-cli stack env ls <name> # secrets are maskedkaio-cli stack env set <name> TAG=1.27 DB_PASSWORD=s3cret [--secret]kaio-cli stack env unset <name> TAGkaio-cli stack env import <name> .env # merge a .env filekaio-cli stack apply <name> # redeploy with the pending environmentImages, volumes, networks
Section titled “Images, volumes, networks”Each of these three nouns exposes the same three commands:
kaio-cli image lskaio-cli image rm <id>kaio-cli image prune
kaio-cli volume lskaio-cli volume rm <name>kaio-cli volume prune
kaio-cli network lskaio-cli network rm <id>kaio-cli network pruneCluster
Section titled “Cluster”See Multiple servers.
On the control plane:
kaio-cli cluster token # print the join token, minting one if there is nonekaio-cli cluster token --rotate # mint a new one; servers holding the old one must rejoinkaio-cli cluster info # control plane? member? neither?On the server joining it:
kaio-cli join <control-plane> --join-token <t> [--name <n>] [--advertise <host:port>]kaio-cli join 10.0.0.1:8080 --token-stdin # read the token from stdinkaio-cli cluster leave # leave: tells the control plane, then forgets--name defaults to the joining server’s own host name; the control plane
sanitises it and suffixes it if it is taken. --advertise is rarely needed:
the server reports its own KAIO_ADDR, and the control plane supplies the
address the request arrived from when that is a wildcard. Pass it when neither
is what others reach the server at: behind NAT, or a reverse proxy.
The Kaio servers that have joined this one. See Multiple servers.
kaio-cli node ls # the cluster, with each node's last probekaio-cli node show <name>kaio-cli node rm <name>kaio-cli node check [<name>] # probe one node, or every node
kaio-cli node <name> run <command> # run any command on that nodenode <name> run forwards through this server’s gateway, so every command works
there: node prod-01 run stack ls, node prod-01 run health, even
node prod-01 run tui. A node that is not in the registry has no route and
answers Node '<name>' has not joined this cluster.
Names that would collide with the subcommands above (ls, show, rm,
check, run, help) are never handed out: a host called run is enrolled as
run-2.
Nodes enter this list by running kaio-cli join on them, and nothing here edits
one: a server is the source of truth about its own address. node rm drops a
member, which comes back by joining again.
System
Section titled “System”kaio-cli system prune [--volumes]Scripting
Section titled “Scripting”--json turns any command into a data source:
# Stacks with a pending updatekaio-cli --json stack ls | jq '.[] | select(.update_available) | .name'# Nodes that are not answeringkaio-cli --json node ls | jq -r '.[] | select(.status != "online") | "\(.name) \(.last_error)"'A pipeline drives these same commands over HTTP, with the published image and its entrypoint overridden: see Deploy from CI.
Kaio, built by Régis Gaidot