-
Notifications
You must be signed in to change notification settings - Fork 1
CLI Reference
Complete reference for every strut command, flag, and subcommand. Each command supports --help for inline usage (e.g. strut my-stack backup --help).
strut <stack> <command> [--env <env>] [options]
| Flag | Description |
|---|---|
--env <name> |
Environment name (reads .<name>.env) |
--services <profile> |
Service profile: messaging, ui, full
|
--json |
JSON output (where supported) |
--dry-run |
Preview destructive operations without executing |
--force-clean |
Allow git clean to delete untracked VPS files (bypass data-loss guard) |
--confirm-data-move |
Proceed even when volume-defining vars changed (data may be lost) |
--no-tui |
Disable the interactive TUI (since v0.19.0) |
STRUT_NO_TUI=1 |
Env-var equivalent of --no-tui (since v0.19.0) |
STRUT_PROJECT |
Override project root detection (env var) |
STRUT_NO_UPDATE_CHECK=1 |
Suppress the version update nag (env var) |
These don't require a stack name:
| Command | Description |
|---|---|
strut |
Interactive TUI picker (stack → command → env) when stdin is a tty (since v0.19.0) |
strut --print |
Same as strut but prints the resolved command instead of running it (since v0.19.0) |
strut init [--registry <type>] [--org <name>] |
Initialize a new project with strut.conf
|
strut list |
List all available stacks |
strut list plugins [--json] |
List discovered project plugins (since v0.17.0) |
strut help <plugin> |
Show a project plugin's help text (since v0.17.0) |
strut scaffold <name> [--recipe <recipe>] |
Create a new stack from templates (optionally from a recipe, since v0.18.0) |
strut scaffold list [--json] |
List available scaffold recipes (since v0.18.0) |
strut sync [<host>|--all] [--env <name>] [--dry-run] [--force-clean] |
Sync VPS checkout with origin (fetch + reset). Resolves hosts via topology alias or env files. (since v0.29.0) |
strut fleet status [--json] |
Git sync state (branch, ahead/behind, dirty, HEAD sha) across every [hosts] in topology (since v0.31.0) |
strut webhook poll [--interval <sec>] [--branch <name>] [--stack <name>] [--once] |
Poll origin, auto-deploy stacks affected by new commits (since v0.32.0) |
strut webhook serve [--port <N>] [--secret <hmac>] [--branch <name>] |
HTTP receiver for GitHub/GitLab push events (HMAC-verified) (since v0.32.0) |
strut webhook install [--mode poll|serve] [--interval <sec>] [--port <N>] |
Generate a systemd unit for persistent webhook operation (since v0.32.0) |
strut mcp serve |
Start the MCP server on stdio for AI agent integration (since v0.33.0) |
strut mcp install [--host <editor>] |
Write MCP config for your editor (via agent-add, or Kiro-only jq fallback) (since v0.33.0) |
strut upgrade |
Upgrade strut to latest version |
strut --version |
Show installed version |
strut skills [list|install] [--format <fmt>] |
AI agent context management |
strut audit <host> [user] [key] [port] |
Audit a VPS |
strut audit:list |
List past audits |
strut audit:diff <host> [user] [key] [port] |
Audit a host and diff against its most recent stored audit (since v0.24.0) |
strut audit:generate <name> --from <dir> |
Generate stack from audit |
strut migrate <host> [user] [port] [key] [--yes] |
Run migration wizard |
strut migrate:status |
Show migration status |
strut monitoring <subcommand> |
Monitoring stack management |
strut doctor [--check-vps] [--deep] [--json] [--fix] |
Diagnostic environment check (--deep runs a full preflight against every configured VPS — Docker, disk, memory, ports, sudo) |
strut status-all [--env <name>] [--json] |
Dashboard showing every stack at once (since v0.11.0) |
strut posture [--stack <name>] [--category <c>] [--fail-on <lvl>] [--json] |
Security/ops posture check (since v0.11.0) |
strut group list|show|add|remove|<name> <cmd> |
Stack group dispatcher (since v0.15.0) |
strut notify test <slack|discord|webhook> |
Send test notification (since v0.9.0) |
strut completions <bash|zsh|fish> |
Print shell completion script (since v0.17.0) |
strut init --completions |
Auto-install completions for current shell (since v0.17.0) |
All require: strut <stack> <command> [--env <name>]
| Command | Description |
|---|---|
release [...] |
Alias for deploy --require-remote, kept for existing scripts |
deploy [--services <profile>] [--pull-only] [--skip-validation] [--skip-health-gate] [--force-unlock] [--no-lock] [--blue-green|--standard] [--force-local] |
Deploy stack containers (concurrency-locked since v0.13.0; blue-green since v0.20.0; health-gated since v0.42.0) |
rebuild [--no-cache] [--pull] |
Build images on target + deploy (since v0.22.0) |
ship [--message <msg>] [-m <msg>] [--no-commit] [--no-push] [--no-cache] |
Commit, push, and rebuild on remote in one step (since v0.22.0) |
stop [--volumes] [--timeout N] |
Stop running containers |
update |
Pull latest strut code on VPS (no container restart) |
diff [--json] |
Preview pending env/image changes vs VPS (since v0.13.0) |
lock <status|release> [--force] [--remote|--local] |
Inspect/manage deploy concurrency locks (since v0.13.0) |
| Command | Description |
|---|---|
health [--json] |
Run health checks against services.conf
|
briefing [--json] |
One-call situation report: aggregates health, drift, image staleness, pending diff, and backup health into an overall posture (ok/warn/critical) plus prioritized actions. Exit code reflects posture (since v0.41.0) |
preflight [--json] |
Deploy go/no-go verdict (GO/CAUTION/NO-GO) fusing pending diff, config drift, current health, and backup freshness, with reasons. Exits 0/1/2 (since v0.41.0) |
logs [service] [--follow] [--since <dur>] |
View service logs |
logs:download [service] [--since <dur>] |
Download logs to local filesystem (since v0.23.0) |
logs:rotate |
Rotate log files on VPS (since v0.23.0) |
status |
Show container status |
| Command | Description |
|---|---|
backup [postgres|neo4j|mysql|sqlite|all] |
Create backups |
backup offsite <status|sync|list|restore <file>> |
Offsite backup sync to S3/R2/B2 (since v0.16.0) |
restore <file> [--dry-run] [--target-env <env>] |
Restore from backup file. --dry-run (Postgres only, since v0.31.0) rehearses into a scratch DB, diffs row counts vs live, then drops it — never touches the live database |
db:pull [type] [--download-only] [--file <name>] |
Pull backup from VPS, restore locally |
db:push [type] [--upload-only] [--file <name>] |
Push local backup to VPS, restore remotely |
db:schema [apply|verify|all] |
Apply or verify Postgres schema SQL |
migrate [neo4j|postgres] [--status|--up|--down N] |
Run database migrations |
| Command | Description |
|---|---|
validate |
Validate all config files against expected schemas |
drift [detect|report|fix|auto-fix|history|images] |
Configuration drift detection. images [--json] (since v0.31.0) flags containers whose running image digest no longer matches what their tag currently resolves to on the registry |
keys <subcommand> |
Key management (SSH, API, env, db, GitHub) |
secrets push|pull|diff|validate |
Sync .env files to/from VPS (since v0.26.0) |
secrets hydrate |
Resolve vault/exec/file references in .env.template → .env (since v0.27.0) |
secrets status |
Show full secrets pipeline state for the stack (since v0.27.0) |
secrets rotate [--restart] |
Re-hydrate → validate → push → optional container restart (since v0.27.0) |
secrets template [--force] |
Reverse-engineer .env.template from existing .env (since v0.27.0) |
secrets export --format <fmt> |
Export .env as docker-secret, k8s-secret, or env-json (since v0.27.0) |
secrets lock [--backend age|gpg] |
Encrypt .env at rest (safe to commit) (since v0.27.0) |
secrets unlock [--identity <file>] |
Decrypt .env.age/.env.gpg back to plaintext (since v0.27.0) |
init-secrets [--force] [--dry-run] |
Generate .env from template with auto-secrets (since v0.25.0) |
ssh:keygen [--name <label>] [--type <ed25519|rsa>] |
Generate deploy keypair + authorize on host (since v0.24.0) |
ci:init [--provider <name>] [--repo <owner/repo>] [--key-name <label>] [--dry-run] [--yes] |
Bootstrap CI/CD secrets for the stack (since v0.27.0) |
volumes [status|init|config] |
Volume management |
domain <domain> <email> [--skip-ssl] |
Configure domain and SSL. Deploys also auto-provision Let's Encrypt certs when AUTO_SSL=true (default) and a domain is detected from a compose label or DOMAIN/DOMAINS/VIRTUAL_HOST (since v0.32.0) — see Domain and SSL
|
cert:renew [--dry-run] |
Renew Tailscale HTTPS certificates on a host (since v0.24.0) |
cert:status |
Show certificate expiry dates (since v0.24.0) |
rollback [--list] [--dry-run] |
Roll back to previous deploy snapshot (blue-green: flips active color, since v0.20.0) |
rollback diff <ref_a> <ref_b> [--json] |
Diff images between two snapshots; refs: HEAD, HEAD~N, basename (since v0.16.0) |
prune [--volumes] [--all] [--no-protect] |
Prune docker resources; --no-protect skips rollback-image protection (since v0.16.0) |
| Command | Description |
|---|---|
ssh:keygen --name <name> |
Generate a deploy keypair and authorize the public key on the VPS host |
ci:init --provider <provider> |
Bootstrap all CI secrets (SSH key, env vars) for the stack on the given provider (e.g. github) |
ci:init --dry-run |
Preview which secrets would be set without writing anything |
| Command | Description |
|---|---|
keys rotate-registry [--registry <url>] [--hosts <list>] |
Rotate Docker registry pull credentials across VPS hosts |
keys registry-status [--registry <url>] [--json] |
Show per-host registry auth state |
| Command | Description |
|---|---|
shell |
SSH to VPS (interactive) |
exec <command> |
Execute single command on VPS |
remote:init [--host <h>] [--user <u>] [--key <k>] [--repo <url>] |
Bootstrap strut on a remote VPS (since v0.21.0) |
provision [--script <path>] [--verify] [--dry-run] |
Run one-time provisioning script on host (since v0.23.0) |
| Command | Description |
|---|---|
gateway deploy --host <alias> |
Deploy Caddyfile to a host and reload Caddy |
gateway status --host <alias> |
Show Caddy service status |
gateway reload --host <alias> |
Reload Caddy without deploying new config |
gateway validate |
Validate local Caddyfile syntax |
| Command | Description |
|---|---|
cert:renew [--dry-run] |
Renew Tailscale HTTPS cert and reload Caddy |
cert:status |
Show certificate subject, issuer, and expiry |
| Command | Description |
|---|---|
ssh:keygen [--name <label>] [--type <ed25519|rsa>] |
Generate deploy keypair and authorize it on the target host |
ci:init [--provider <name>] [--repo <owner/repo>] [--key-name <label>] [--dry-run] [--yes] |
Bootstrap CI/CD secrets for the stack |
ci:init options:
| Flag | Description |
|---|---|
--provider <name> |
CI provider: github (default), gitlab, manual
|
--repo <owner/repo> |
Target repo (default: auto-detect from git remote) |
--key-name <label> |
Deploy key name (default: ci) |
--dry-run |
Show what secrets would be set without executing |
--yes |
Push secrets without confirmation (requires gh/glab CLI) |
Secret categories discovered:
| Category | Meaning |
|---|---|
| AUTO | Derived from strut.conf topology (host, user, port, deploy dir) |
| KEY | Deploy key file (from ssh:keygen) |
| ENV | Value read from the stack's .env file or ci_secrets manifest |
| MANUAL | Requires human input (prints instructions) |
ci_secrets manifest: If stacks/<stack>/ci_secrets exists, each line names an env var to include. Otherwise ci:init uses heuristics (vars matching *API_URL*, *API_TOKEN*, etc.).
| Command | Description |
|---|---|
debug exec <service> <command> |
Execute command in container |
debug shell <service> |
Open interactive shell in container |
debug port-forward <service> <local>:<remote> |
Forward port from container |
debug copy <service> <source> <dest> |
Copy files to/from container |
debug snapshot <service> |
Create container snapshot |
debug inspect-env <service> |
Show environment variables |
debug stats <service> |
Show real-time resource usage |
| Command | Description |
|---|---|
local start [--services <profile>] |
Start stack locally |
local stop |
Stop local stack |
local reset |
Reset local environment |
local sync-env --from <env> |
Sync env vars from production |
local sync-db --from <env> [target] [--anonymize] |
Sync database from production |
local logs [--follow] |
Tail local logs |
local test |
Run local smoke tests |
strut monitoring deploy # Deploy monitoring stack
strut monitoring add-target <stack> [env] # Add stack to monitoring
strut monitoring remove-target <stack> # Remove from monitoring
strut monitoring alert-channel add <type> [options] # Configure alerts
strut monitoring alert-channel test [type] # Test alert delivery
strut monitoring status [--json] # Show monitoring statusGroups are declared in groups.conf (INI-style) and run a strut command across every stack in the group.
strut group list # List all groups
strut group show <name> # List members of a group
strut group add <name> <stack> # Append a stack
strut group remove <name> <stack> # Remove a stack
strut group <name> <command> [--env <env>] [--stop-on-error] [--json]
strut group <name> logs [--follow] [--since <dur>] [--grep <pat>] [--service <svc>]group <name> logs multiplexes logs across every member with a colored [stack] prefix. All other commands shell out to strut <stack> <command> per member and collect pass/fail. See Stack Groups.
strut notify test slack # Send a test event to SLACK_WEBHOOK
strut notify test discord
strut notify test webhookProviders are configured in notifications.conf at the project root. See Notifications.
| Profile | Description |
|---|---|
| (none) | Core services (default compose file) |
gdrive |
Core + Google Drive ingestion |
messaging |
Core + messaging service |
ui |
Core + UI service |
full |
All services |
# Deploy to wherever the stack lives
strut my-app deploy --env prod
# Preview before deploying
strut my-app deploy --env prod --dry-run
# Deploy with all services
strut my-app deploy --env prod --services full
# Ship: commit, push, and rebuild on remote
strut my-app ship --env prod -m "fix dashboard layout"
strut my-app ship --env prod --no-commit # skip commit, just push + rebuild
# Build images on remote (without local git flow)
strut my-app rebuild --env prod --no-cache
# Health check with JSON output
strut my-app health --env prod --json
# Follow logs for a specific service
strut my-app logs api --follow --env prod
# Backup all databases
strut my-app backup all --env prod
# Pull production database locally
strut my-app db:pull --env prod
# Check for config drift
strut my-app drift detect --env prod
# Rotate database passwords
strut my-app keys db:rotate postgres --env prod
# Configure domain with SSL
strut my-app domain api.example.com admin@example.com --env prod
# Secrets management
strut my-app init-secrets --env prod # Generate .env from template
strut my-app secrets push --env prod # Upload .env to VPS
strut my-app secrets pull --env prod # Download .env from VPS
strut my-app secrets diff --env prod # Compare local vs remote
strut my-app secrets hydrate --env prod # Resolve vault/exec/file refs → .env
strut my-app secrets status --env prod # Show secrets pipeline state
strut my-app secrets rotate --env prod --restart # Full rotate + container restart
strut my-app secrets template --env prod # Reverse-engineer .env.template
strut my-app secrets export --format k8s-secret # Export as Kubernetes Secret manifest
strut my-app secrets lock --env prod # Encrypt .env at rest (age/gpg)
strut my-app secrets unlock --env prod # Decrypt to plaintext for editing
# Registry credential rotation
strut my-app keys rotate-registry --registry ghcr.io
strut my-app keys registry-status --json
# Deploy keys & CI setup
strut my-app ssh:keygen --name ci # Generate deploy keypair
strut my-app ci:init # Print CI secrets checklist
strut my-app ci:init --provider github --yes # Push secrets via gh CLI
strut my-app ci:init --dry-run # Preview what would be set
strut my-app ci:init --repo gfargo/my-app # Explicit repo target
# Certificate management
strut harbor cert:renew # Renew Tailscale cert
strut harbor cert:status # Check cert expiry
# Gateway management
strut gateway deploy --host harbor # Deploy Caddyfile to host
strut gateway status --host harbor # Check Caddy status
strut gateway validate # Validate local Caddyfile syntax
# Provisioning
strut harbor provision # Run provision script
strut harbor provision --verify # Verify only
# List all stacks
strut list
# Create a new stack
strut scaffold my-new-app
# Cross-stack dashboard
strut status-all --env prod
strut status-all --env prod --json
# Security/ops posture audit (CI-friendly exit codes)
strut posture
strut posture --category secrets --fail-on warn --json
# Preview deploy changes vs VPS
strut my-stack diff --env prod
# Blue-green deploy (zero-downtime swap)
strut my-stack deploy --env prod --blue-green
strut my-stack deploy --env prod --blue-green --dry-run
strut my-stack rollback --env prod # flips back to drained color
# Diff two rollback snapshots
strut my-stack rollback diff HEAD~1 HEAD
strut my-stack rollback diff 20260420-091500 HEAD --json
# Group operations
strut group list
strut group vps-1 deploy --env prod
strut group vps-1 logs --follow
# Deploy keys & CI setup
strut my-stack ssh:keygen --name ci # Generate deploy keypair + authorize on host
strut my-stack ci:init --provider github # Bootstrap all CI secrets for the stack
strut my-stack ci:init --dry-run # Preview what secrets would be set
# Offsite backup sync
strut my-stack backup offsite status --env prod
strut my-stack backup offsite sync --env prod
strut my-stack backup offsite list --env prod
# Non-destructive restore rehearsal (Postgres) — never touches the live DB
strut my-stack restore backups/postgres-20260701.sql --env prod --dry-run
# Fleet sync state across every configured host
strut fleet status
strut fleet status --json
# Stale image-digest detection (mutable tag moved on the registry since deploy)
strut my-stack drift images --env prod --json
# Webhook push-to-deploy
strut webhook poll --once # single check, e.g. from cron
strut webhook serve --port 9876 --secret "$WEBHOOK_SECRET" # HTTP receiver
strut webhook install --mode poll > strut-webhook.service # generate a systemd unit
# MCP server for AI agent integration
strut mcp install --host cursor # write MCP config for a specific editor
strut mcp install # interactive editor pickerstrut · v0.28.0 · Report an Issue
Getting Started
Core Concepts
Operations
- Deployment
- Ship and Rebuild
- GitHub Action
- Webhook Automation
- Remote Host Setup
- Provisioning
- Blue-Green Deploy
- Deploy Rollback
- Database Backups
- Secrets Management
- Stack Groups
- Lifecycle Hooks
- Notifications
- Key Rotation
- Drift Detection
- Domain and SSL
- Certificate Management
- Gateway Management
- Monitoring
- Volume Management
Advanced
- Security Posture
- VPS Audit and Migration
- Stack Validation
- Data Anonymization
- Debugging
- Local Development
Extending
Contributing