CLI Command Reference¶
Verified CLI commands — exact syntax that works. Add new entries when a command succeeds.
Purpose: Avoid repeating wrong CLI syntax across sessions.
km (Komodo CLI)¶
Deploy stack (compose-only changes)¶
- Feature: Deploy stack after git push (compose.yaml changes only)
- Gotcha: Must pipe empty string to skip confirmation prompt
Deploy stack with sync (TOML changes)¶
- Feature: Sync TOML from git then deploy stack
- Gotcha: Two separate commands chained, both need empty pipe for non-interactive
Run command inside container (non-interactive)¶
ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no root@100.68.251.84 "docker exec <container-name> <shell-command>"
- Feature: Run non-interactive command inside running container on unraid (docker exec equivalent)
- Gotcha: Must use SSH —
km execis interactive-only (requires TTY),km x execparses askm execute exec(wrong subcommand). For development server usessh 100.126.172.96 "docker exec <container> <cmd>"
Restart / Stop / Start stack¶
echo "" | km x restart-stack <name>
echo "" | km x stop-stack <name>
echo "" | km x start-stack <name>
- Feature: Lifecycle operations on deployed stacks
Get container/stack logs¶
km-logs <container> # container logs (auto-detect server)
km-logs <container> -n 100 # tail 100 lines (default: 50)
km-logs <container> -t # with timestamps
km-logs <container> -g error -g fail # grep AND search
km-logs -S <stack> [services...] # stack compose logs
- Feature: Wrapper script at
scripts/km/km-logs— reads Komodo API directly, no SSH needed - Gotcha: This is NOT a native
kmsubcommand. Symlinked to~/.local/bin/km-logs
Run resource sync¶
- Feature: Trigger resource sync manually (pulls git changes into Komodo)
List stacks / servers / containers¶
km list stacks # all stacks
km list servers # all servers
km container # running containers (alias: km cn, km ps)
km container -a # all containers including stopped
km container -a | grep <name> # filter by name
- Feature: Query Komodo for deployed resources and container states
- Gotcha:
km container(aliaskm cn) notkm list containers. Use-afor stopped,-dfor down-only
Server stats (via API — no native km command)¶
KEY=$(grep key ~/.config/komodo/komodo.cli.toml | head -1 | sed 's/.*= "//;s/"//')
SECRET=$(grep secret ~/.config/komodo/komodo.cli.toml | head -1 | sed 's/.*= "//;s/"//')
curl -s -X POST -H "x-api-key: $KEY" -H "x-api-secret: $SECRET" \
-H "Content-Type: application/json" -d '{"server":"<name>"}' \
"http://100.126.172.96:9120/read/GetSystemStats"
- Feature: CPU, memory, disk usage for a server
docker / docker compose¶
Check container status on remote server¶
- Feature: Check if container is running on remote server
- Gotcha: Only use for debugging/investigation, NEVER for deployment
Inspect container network¶
- Feature: Get container IP address
Follow container logs¶
- Feature: Stream container logs in real-time
tailscale¶
Check Tailscale status¶
- Feature: Show all Tailscale peers and their IPs
Get device IP¶
- Feature: Resolve Tailscale IPv4 for a device
bd (Beads Issue Tracker)¶
Find available work¶
- Feature: List issues ready to be worked on
View issue details¶
- Feature: Display full issue content
Claim and update issue¶
- Feature: Claim ownership of an issue
Close completed work¶
- Feature: Mark issue as completed
Save persistent knowledge¶
- Feature: Save fact for future sessions
Push changes to remote¶
- Feature: Push bd issue tracker state to remote
uv (Python Package Manager)¶
Install dependencies¶
- Feature: Sync project dependencies (dev adds ruff, mypy, yamlfix)
Run tool via uv¶
- Feature: Run linting tools without activating venv
gh (GitHub CLI)¶
Create PR¶
- Feature: Create pull request from current branch
View PR checks¶
- Feature: Show CI status for current PR
rclone (unraid)¶
List remotes¶
- Feature: List all configured remotes in current config
- Gotcha:
rcloneon unraid is a 95-byte shim callingrcloneorig(plugin's renamed binary) with--config=/boot/config/plugins/rclone/.rclone.conf. Real binary is/usr/bin/rclone(uses main config at/root/.config/rclone/rclone.conf)
Show one remote¶
- Feature: Display config of a single remote (token shown in plain)
Test OneDrive/Microsoft Graph connection¶
- Feature: List folders, list files, show quota
Authorize new remote (CLI-only flow, headless)¶
# On machine with browser (local):
rclone authorize <type> # e.g. onedrive, drive, dropbox
# → Browser opens, login, copy JSON token printed to terminal
# On unraid (or target server), append to config:
# [remote]
# type = onedrive
# region = global
# drive_id = <id>
# drive_type = personal
# token = <JSON from rclone authorize>
OneDrive gotcha — drive_id/drive_type auto-detect fails for personal accounts¶
- Issue:
rclone lsd onedrive:fails withunable to get drive_id and drive_typeeven with valid token (token verified OK viacurl https://graph.microsoft.com/v1.0/me/drivereturns 200) - Fix: Manually set explicit values:
- Workaround:
curl -H "Authorization: Bearer $TOKEN" https://graph.microsoft.com/v1.0/me/drive | grep -oE '"id":"[^"]+"' | head -1
Two config files on unraid¶
| File | Used by | Notes |
|---|---|---|
/root/.config/rclone/rclone.conf |
Real /usr/bin/rclone (mount scripts if they use this) |
Personal/staging edits |
/boot/config/plugins/rclone/.rclone.conf |
rcloneorig shim, web UI :5572, mount-cloud.sh |
Plugin-owned, persists in /boot |
- Sync both after edits to keep them consistent (except tokens will diverge as they refresh)
Backup config before edit¶
TS=$(date +%Y%m%d-%H%M%S)
cp /root/.config/rclone/rclone.conf /root/.config/rclone/rclone.conf.bak-${TS}
cp /boot/config/plugins/rclone/.rclone.conf /boot/config/plugins/rclone/.rclone.conf.bak-${TS}
GitOps One-liners¶
Standard deploy (compose-only)¶
git add -A && git commit -m "chore(<stack>): <message>" && git push && echo "" | km x deploy-stack <name>
Deploy with sync (TOML changes)¶
git add -A && git commit -m "chore(<stack>): <message>" && git push && echo "" | km x run-sync <category> && echo "" | km x deploy-stack <name>
Session close¶
- Feature: Full session close sequence
- Gotcha: All three must succeed before session is complete
tofu (OpenTofu / Cloudflare)¶
Check drift against live infrastructure¶
```bash export AWS_ACCESS_KEY_ID="$(atuin dotfiles var list | grep R2_ACCESS_KEY_ID | sed 's/export R2_ACCESS_KEY_ID=//')" export AWS_SECRET_ACCESS_KEY="$(atuin dotfiles var list | grep R2_SECRET_ACCESS_KEY | sed 's/export R2_SECRET_ACCESS_KEY=//')" export CLOUDFLARE_API_TOKEN="$(atuin dotfiles var list | grep CLOUDFLARE_API_TOKEN | sed 's/export CLOUDFLARE_API_TOKEN=//')" tofu plan ```
- Feature: Compares local TF config against Cloudflare + R2 state, shows drift
- Gotcha: Credentials named
R2_*in atuin, must remap toAWS_*env vars. Must be ininfrastructure/cloudflare/dir (or use-chdir)
Bulk domain health check¶
```bash for entry in vault=vaultwarden git=gitea z=litellm alist=openlist dns=adguard home=homepage komodo=komodo ntfy=ntfy-via-lan photo=immich; do domain="${entry%%=*}"; svc="${entry##*=}" printf "%-22s %-16s " "$domain.minhluc.info" "[$svc]" curl -sS -o /dev/null -w "%{http_code} %{size_download}B %{time_total}s" --max-time 8 "https://$domain.minhluc.info" 2>&1 echo done ```
- Feature: Check HTTP status + response size + latency for all tunnel domains, with service mapping
- Gotcha: 502 = container not running (config OK), 000 = DNS/tunnel issue. vault slow (~8s) normal
Read Komodo deployment stderr via API¶
```bash
curl -s -X POST \
-H "x-api-key: $(grep key ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "x-api-secret: $(grep secret ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "Content-Type: application/json" \
-d '{"id":"
- Feature: Get full deployment log (stdout + stderr per stage) for any Komodo update
- Gotcha: UPDATE_ID from
km x deploy-stackoutput link (e.g.6a26edb5cc0c77a6d6999641). Auth usesx-api-key/x-api-secretheaders, NOT Basic auth
Destroy orphaned container via Komodo API¶
```bash
curl -s -X POST \
-H "x-api-key: $(grep key ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "x-api-secret: $(grep secret ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "Content-Type: application/json" \
-d '{"server":"unraid","container":"
- Feature: Remove container that
destroy-stackcan't reach (orphaned, name conflict) - Gotcha: Use full container SHA or name.
destroy-stackonly removes containers in the project
SSH to unraid via Tailscale¶
```bash
ssh -o StrictHostKeyChecking=no root@100.68.251.84 "
- Feature: Run commands on unraid host directly (write appdata, docker commands, etc.)
- Gotcha: Root access, no password needed (Tailscale auth). Use for host-level ops that containers can't do
Komodo REST API (Verified 2026-06-08)¶
All commands verified against live Komodo v2.2.0. Auth pattern is same for all.
Get stack logs via API¶
```bash
curl -s -X POST \
-H "x-api-key: $(grep key ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "x-api-secret: $(grep secret ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "Content-Type: application/json" \
-d '{"stack":"
- Feature: Get container stdout logs for a stack (returns
{"stdout":"..."}) - Verified: caddy → 1 line. Use
SearchStackLogwith{"stack":"<name>","terms":["error"]}for filtered search
Search stack logs with terms¶
```bash
curl -s -X POST \
-H "x-api-key: $(grep key ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "x-api-secret: $(grep secret ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "Content-Type: application/json" \
-d '{"stack":"
- Feature: AND-search stack logs (all terms must match)
Inspect container via API¶
```bash
curl -s -X POST \
-H "x-api-key: $(grep key ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "x-api-secret: $(grep secret ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "Content-Type: application/json" \
-d '{"server":"unraid","container":"
- Feature: Full docker inspect JSON (Name, State, NetworkSettings, etc.)
- Verified: caddy →
{"Name":"/caddy","State":{"Status":"running"}}
Get server system stats¶
```bash
curl -s -X POST \
-H "x-api-key: $(grep key ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "x-api-secret: $(grep secret ~/.config/komodo/komodo.cli.toml | sed 's/.= "//;s/"//')" \
-H "Content-Type: application/json" \
-d '{"server":"
- Feature: CPU%, memory (used_gb/total_gb), disk stats
- Verified: unraid → mem=24.18/31.14GB
Quick verify pattern (auth + endpoint)¶
```bash KEY=$(grep key ~/.config/komodo/komodo.cli.toml | head -1 | sed 's/.*= "//;s/"//') SECRET=$(grep secret ~/.config/komodo/komodo.cli.toml | head -1 | sed 's/.*= "//;s/"//') curl -s -X POST -H "x-api-key: $KEY" -H "x-api-secret: $SECRET" \ -H "Content-Type: application/json" -d '{}' \ "http://100.126.172.96:9120/read/GetVersion"
→¶
```
- Feature: Verify auth works. Use this pattern as template for all endpoints.
- Gotcha: Headers MUST be quoted:
-H "x-api-key: $KEY"(not-H x-api-key:$KEY)