Documentation menu

CLI reference

One binary, a handful of verbs. VM lifecycle on top, cluster and registry management below. Every command and flag here is taken straight from the binary's own help text.

Global usage

Persistent flags apply to every command. --config (short -c) points at an alternate config file; it defaults to ~/.klimax/config.yaml.

$ klimax [-c ~/.klimax/config.yaml] [--debug] [--lima-log-level <level>] <command>
FlagDescription
-c, --config <path>Path to the klimax config file (default ~/.klimax/config.yaml).
--debugEnable klimax debug logging — and surface Lima's own logs at info.
--lima-log-level <level>Show the embedded Lima VM logs at this level: trace, debug, info, warn, error, or off. Hidden by default.
📖

This page is a curated summary. For the authoritative, always-current flag list run klimax <command> --help — the binary is the source of truth.

Logging

klimax's own output uses Go's log/slog; the embedded Lima library logs through logrus. By default klimax quiets Lima to error, so you see klimax's messages plus any genuine Lima errors — the noisy INFO[…]/WARN[…] Lima lines are hidden. Turn them on when you need to debug the VM itself:

You want…Run
Default — quiet Lima, klimax only(nothing — this is the default)
klimax debug + Lima at infoklimax --debug <command>
Lima at a specific levelklimax --lima-log-level info <command>
Full Lima firehoseklimax --lima-log-level trace <command>
Silence Lima entirely (panic-only)klimax --lima-log-level off <command>
# See what Lima is doing while the VM comes up
$ klimax --lima-log-level info up

# klimax debug detail, with Lima surfaced at info
$ klimax --debug up
🔎

An explicit --lima-log-level wins over --debug. Levels: trace · debug · info · warn · error · off (none/quiet/silent also work). VM readiness detection is unaffected — the in-VM hostagent keeps its own verbose logs regardless.

VM lifecycle

CommandDescription
klimax upCreate/start the VM, provision Docker, create kind clusters, set up routing (idempotent).
klimax downStop the VM — preserves all clusters and registry cache data.
klimax down --remove-routeAlso remove the macOS host route (requires sudo).
klimax destroyDelete kind clusters, delete the VM, and remove the macOS route.
klimax statusShow VM state, clusters, route, and iptables rule presence.
klimax doctorDiagnose issues and print actionable fix commands.
klimax shellOpen an interactive SSH session in the klimax VM (alias ssh).
klimax shell <cmd> [args…]Run a command in the VM and exit with its exit code.
klimax copy <src>… <dst>Copy files between the host and the VM over scp (alias cp).
klimax disk resize <size>Grow the VM disk — applied on the next VM start.
klimax pruneRemove klimax's reclaimable cached files.
klimax config editOpen the klimax config file in $EDITOR.
klimax versionPrint the klimax version.
# Bring everything up — prompts for sudo once to add the host route
$ klimax up

# Stop the VM but keep clusters and cache
$ klimax down

# Tear it all down: VM, clusters, and the host route (sudo)
$ klimax destroy

klimax down keeps the host route in place. Use --remove-route (or klimax destroy) to drop it — either requires sudo. To stop being prompted at all, install the sudoers rules.

After upgrading klimax, re-create the VM. Provisioning is baked into the binary, so klimax down/up on an existing VM keeps running the old setup. Run klimax destroy && klimax up once after each brew upgrade --cask klimax — the host-backed image cache survives, so it rebuilds fast.

Running commands in the VM

Bare klimax shell opens an interactive session. Give it a command and it runs that in the VM instead, passing stdin/stdout/stderr straight through and exiting with the remote exit code — so it composes in pipelines and if tests without reaching for limactl.

FlagDescription
-t, --ttyForce pseudo-terminal allocation — for commands that need one (htop, an editor).
$ klimax shell                                # interactive session
$ klimax shell docker ps -a                   # flags after the command are passed through
$ klimax shell -- bash -c 'kind get clusters' # -- when a flag could look like klimax's
$ cat setup.sh | klimax shell bash -s         # stdin is piped in
$ klimax shell -t htop                        # force a pseudo-terminal

Flag parsing stops at the first positional argument, so klimax shell docker ps -a works as typed — the -a goes to docker, not to klimax. Use -- only when the first word could be mistaken for a klimax flag. Because the exit code is the remote command's, if klimax shell test -e /run/docker.sock; then … behaves like a local test.

Copying files

Moves files in either direction over scp. Mark the VM side with a vm: prefix (the VM's configured name works too); exactly one side of the copy must carry it.

FlagDescription
-r, --recursiveCopy directories recursively.
$ klimax copy ./script.sh vm:/tmp/script.sh   # host → VM
$ klimax copy vm:/tmp/out.json ./out.json     # VM → host
$ klimax copy -r ./manifests vm:/tmp/          # directories
$ klimax copy a.yaml b.yaml vm:/tmp/           # many sources → a directory
📁

Multiple sources are allowed when the destination is a directory. To copy within the VM, use klimax shell cp … — two vm: sides are rejected.

Growing the disk

Grows the VM disk without recreating the VM. The new size is written to vm.disk in the klimax config and to the Lima instance config; Lima expands the image on the next start and the guest root filesystem grows during boot. So it lands after a restart:

$ klimax disk resize 80GiB   # rewrites vm.disk and the Lima instance config
$ klimax down && klimax up   # Lima expands the image; the guest FS grows on boot
$ klimax shell df -h /       # confirm the new headroom

Shrinking is refused — neither Lima nor the guest filesystem supports it. Requesting the current size is a no-op. If the VM doesn't exist yet, only the config is updated and the next klimax up creates the disk at the new size.

Reclaiming space

Removes files klimax can re-create: superseded Lima guest agents under ~/.klimax/share/lima, and registry cache directories whose mirror is no longer in your config (after renaming or removing one). It lists what it found, grouped and sized, and confirms before deleting.

FlagDescription
--dry-runShow what would be removed, remove nothing.
--downloadsAlso clear Lima's image download cache — shared with every other Lima instance on the host.
-y, --yesSkip the confirmation prompt (required to run non-interactively).
$ klimax prune --dry-run     # show what would go
$ klimax prune               # confirm, then remove
$ klimax prune --downloads   # also Lima's shared image download cache

--downloads clears a cache in the OS cache directory that Lima shares across toolslimactl, Colima, Rancher Desktop. Their next start re-downloads its base images too.

Caches of configured mirrors are never touched by prune — that's klimax registry clean-cache. And prune keeps the guest agent matching the Lima version of the binary you run it with, so pruning with a different klimax build removes that build's agent; harmless, it re-downloads on its next klimax up.

Host setup

Two commands that configure the Mac rather than the VM: one grants klimax up the single privilege it needs, the other starts the VM at login.

CommandDescription
klimax sudoersPrint a sudoers snippet so klimax up can manage the host route without a password.
klimax sudoers --checkReport whether those rules are in effect.
klimax autostart installInstall and load a per-user launchd agent that runs klimax up at login.
klimax autostart statusShow whether the agent is installed and loaded.
klimax autostart uninstallUnload and remove the agent (alias remove).

Passwordless host route

klimax up needs root for exactly one thing: the macOS route for the kind bridge CIDR. klimax sudoers prints NOPASSWD rules scoped to those two /sbin/route invocations — the add and the delete, with the gateway wildcarded, because macOS assigns the VM's lima0 IP dynamically. Grant that and up stops prompting:

$ klimax sudoers | sudo tee /etc/sudoers.d/klimax >/dev/null
$ sudo chmod 0440 /etc/sudoers.d/klimax
$ sudo visudo -c -f /etc/sudoers.d/klimax   # verify the syntax
$ klimax sudoers --check
✓ Passwordless route rules for 172.30.0.0/16 are in effect.
🔑

The rules are scoped to the configured CIDR, so regenerate them after changing network.kindBridgeCIDR. --check reads the sudo policy rather than trying the commands — a cached sudo credential would let a trial run succeed whether or not the rules exist.

Starting at login

Installs a per-user launchd agent, dev.klimax.autostart, at ~/Library/LaunchAgents/ that runs klimax up when you log in. Output is appended to ~/.klimax/logs/autostart.log.

$ klimax autostart install           # write the plist and load it
$ klimax autostart install --print   # emit the plist to stdout instead
$ klimax autostart status
$ klimax autostart uninstall
🔑

Install the sudoers rules first. launchd cannot answer a password prompt, so without them the VM comes up at login without the host route and nothing in 172.30.0.0/16 is reachable from the Mac. klimax sudoers --check confirms you're set.

🍺

The plist records the klimax binary by the path you invoked — with the Homebrew cask that's the stable /opt/homebrew/bin/klimax symlink, so the agent keeps working across brew upgrade --cask klimax. The --config path is baked in the same way.

Docker access

Point your host's docker CLI at the daemon inside the VM, either per-shell with an environment variable or persistently with a Docker context.

CommandDescription
klimax docker-envPrint the export command to point DOCKER_HOST at the klimax VM.
klimax docker-env --unsetPrint commands to unset the Docker environment.
klimax docker-contextCreate/switch to the klimax Docker context.
klimax docker-context --unsetSwitch back to the default Docker context.
# Option A — environment variable, current shell only
$ eval $(klimax docker-env)
$ eval $(klimax docker-env --unset)

# Option B — Docker context, persistent across shells
$ klimax docker-context
$ klimax docker-context --unset
🐳

If DOCKER_HOST is set it overrides the active Docker context — use one or the other.

Clusters

Cluster lifecycle lives entirely under klimax cluster — there is no cluster list in the config file. For declarative, multi-cluster workflows see Fleet management and the Fleet resource.

CommandDescription
klimax cluster create <name>Create a new kind cluster in the running VM.
klimax cluster apply -f <file>Create a fleet of clusters from a Fleet manifest (additive; honours dependsOn).
klimax cluster delete [name]Delete a kind cluster (interactive picker when no name is given).
klimax cluster delete -f <file>Delete every cluster listed in a Fleet manifest (reverse-dependency order).
klimax cluster delete -l <selector>Delete clusters whose nodes match a label selector.
klimax cluster listList kind clusters running in the VM (filter with -l <selector>).
klimax cluster label <name>Add, overwrite, or remove node labels on an existing cluster.
klimax cluster e2e-test-nginxDeploy nginx and curl it via LoadBalancer to verify the cluster end-to-end.
klimax cluster use / mergeDeprecated — use kubeconfig env / merge (or kubeconfig use to switch context).

cluster create flags

FlagDescription
--region <r>topology.kubernetes.io/region label (default europe-west<N>).
--zone <z>topology.kubernetes.io/zone label (default europe-west<N>-b).
-l, --label <k=v>Extra node label; repeatable. All nodes also get managed-by=klimax.

The cluster num (subnet/port slot) is always auto-assigned to the lowest free value. To pin one, use a Fleet manifest's per-cluster num: field.

$ klimax cluster create dev
$ klimax cluster create dev --region us-east1 --zone us-east1-a
$ klimax cluster create dev -l team=search -l env=dev

Fleets — apply & delete -f

Create or tear down a whole fleet of clusters from one Fleet manifest. apply is additive — it creates the clusters that don't exist yet, in dependsOn order, up to maxParallel at a time — and never mutates running clusters.

FlagApplies toDescription
-f, --filename <path>apply, deletePath to a Fleet manifest; - reads stdin.
--dry-runapplyValidate and print the resolved plan, then exit without creating anything.
--max-parallel <N>applyOverride spec.maxParallel (concurrent cluster creations).
-y, --yesdeleteSkip the confirmation prompt.
$ klimax cluster apply -f fleet.yaml --dry-run   # preview the plan
$ klimax cluster apply -f fleet.yaml              # create what's missing
$ cat fleet.yaml | klimax cluster apply -f -      # from stdin
$ klimax cluster delete -f fleet.yaml -y          # tear the fleet down

Listing, switching, merging

cluster list takes -o / --output with text (default), json, or yaml, and -l / --selector to filter by a kubectl-style node-label selector.

$ klimax cluster list
$ klimax cluster list -o json
$ klimax cluster list -l env=dev                    # filter by label selector
$ klimax cluster list -l klimax.dev/fleet=dev-fleet

Pointing kubectl at a cluster now lives under klimax kubeconfig:

# Use one cluster's isolated kubeconfig in this shell
$ eval $(klimax kubeconfig env dev)

# Or merge it into ~/.kube/config and switch to it
$ klimax kubeconfig use dev

Labeling clusters

Relabel the nodes of a cluster that's already running — no recreate needed. Repeatable -l key=value sets or overwrites a label (--overwrite is the default); -l key- removes one. It runs kubectl label nodes --all under the hood.

$ klimax cluster label dev -l tier=frontend -l disktype=ssd
$ klimax cluster label dev -l disktype-              # remove the label

Deleting clusters

Pass a name to delete one cluster, run it bare for an interactive multi-select picker, or match a set with -l / --selector (confirms unless -y).

$ klimax cluster delete staging
$ klimax cluster delete                    # interactive picker (Space toggles)
$ klimax cluster delete -l env=test --yes   # delete all matching, no prompt

End-to-end smoke test

Runs against your current kubectl context. --cleanup removes the test workload instead of deploying it.

$ klimax cluster e2e-test-nginx
$ klimax cluster e2e-test-nginx --cleanup   # delete the nginx pod and service

Kubeconfig

Every cluster keeps an isolated kubeconfig. The klimax kubeconfig family (alias klimax kc) prints its path, exports it, or merges it into your default ~/.kube/config.

CommandDescription
klimax kubeconfig path <name>Print the path to the cluster's kubeconfig file.
klimax kubeconfig env <name>Print export KUBECONFIG=<path>eval it to use the cluster's isolated kubeconfig in the current shell.
klimax kubeconfig merge <name>Merge the cluster's context into ~/.kube/config.
klimax kubeconfig use <name>Merge and switch the active kubectl context to it.
klimax kubeconfig remove <name>Remove the cluster's context, cluster, and user from ~/.kube/config (alias rm).
$ eval $(klimax kubeconfig env dev)   # use dev's isolated kubeconfig here
$ klimax kubeconfig use dev           # merge + switch active context
$ klimax kubeconfig path dev
$ klimax kubeconfig remove dev        # clean it out of ~/.kube/config

klimax cluster use and cluster merge still work as deprecated aliases — cluster use maps to kubeconfig env, cluster merge to kubeconfig merge. Prefer the kubeconfig forms.

Fleets

The top-level klimax fleet command operates on live clusters grouped by the klimax.dev/fleet=<name> node label (membership is derived from running clusters, not the manifest). See Fleet management and the Fleet resource.

CommandDescription
klimax fleet listGroup clusters by klimax.dev/fleet (-o text/json/yaml).
klimax fleet describe <name>Show a fleet's members with their num, ports, nodes, and labels (aliases desc, show).
klimax fleet create -f <file>Create a manifest's clusters — delegates to cluster apply -f (--dry-run, --max-parallel).
klimax fleet delete <name>Delete a fleet's clusters, resolved by label (-y to skip the prompt).
klimax fleet delete -f <file>Delete a manifest's clusters — same as cluster delete -f.
klimax fleet label <name> -l <k=v>Apply node labels to every cluster in the fleet (-l key- removes).
$ klimax fleet list
$ klimax fleet describe dev-fleet
$ klimax fleet create -f fleet.yaml --dry-run
$ klimax fleet label dev-fleet -l tier=frontend
$ klimax fleet delete dev-fleet -y

Registry

CommandDescription
klimax registry clean-cacheRemove all registry mirror cache data and their containers.
$ klimax registry clean-cache
$ klimax up                       # restart the mirrors afterwards

With the default cacheStorage: "host", mirror blobs live at ~/.klimax/registry-cache/ and survive klimax destroy. clean-cache is how you wipe them on purpose. See Registry mirrors.

Skill

Install the klimax Agent Skill so AI coding tools like Claude Code know how to drive klimax.

CommandDescription
klimax skill installInstall the bundled SKILL.md into an AI tool's skills directory (Claude Code by default).
klimax skill pathPrint where the skill is installed for Claude Code.
Flag (on install)Description
--claudeInstall into ~/.claude/skills/klimax/ (default true).
--printWrite the skill to stdout instead of installing.
-f, --forceOverwrite an already-installed skill.
$ klimax skill install            # → ~/.claude/skills/klimax/SKILL.md
$ klimax skill install --print     # emit to stdout for other tools
$ klimax skill path

Completion

Generate a shell auto-completion script for bash, zsh, fish, or powershell.

# zsh — add to ~/.zshrc to persist
$ source <(klimax completion zsh)

# bash
$ source <(klimax completion bash)

# fish
$ klimax completion fish > ~/.config/fish/completions/klimax.fish

See also