Skip to main content

CLI Reference

Command Index

CommandPhasePurpose
kindling initSetupBootstrap Kind cluster + operator
kindling runnersSetupRegister CI runner pool (GitHub/GitLab)
kindling explainSetupOn-demand kindling concepts/workflow guidance
kindling analyzeSetupCheck project readiness
kindling generateSetupAI-generate CI workflow
kindling deployDevelopApply DSE from YAML file
kindling pushDevelopRebuild + redeploy one service via CI
kindling syncDevelopLive-sync files into running pod
kindling debugDevelopAttach VS Code debugger to deployment
kindling devDevelopFrontend dev server with cluster access
kindling loadDevelopBuild + load image into Kind directly
kindling dashboardDevelopLaunch web dashboard
kindling exposeDevelopPublic HTTPS tunnel to cluster
kindling envDevelopManage deployment env vars
kindling secretsDevelopManage external credentials
kindling ingressDevelopManage extra Ingress routes on a DSE
kindling depsDevelopManage shared dependency resources
kindling statusDevelopCluster + environment status
kindling logsDevelopTail controller logs
kindling snapshotStagingExport Helm/Kustomize + deploy
kindling staging tlsStagingConfigure TLS with cert-manager
kindling resetLifecycleRemove runner pool, keep cluster
kindling destroyLifecycleDelete cluster and all resources
kindling versionPrint CLI version

Installation

brew install kindling-sh/tap/kindling

Build from source:

cd kindling && make cli
sudo cp bin/kindling /usr/local/bin/

Global Flags

FlagShortDefaultDescription
--cluster-cdevKind cluster name
--project-dir-p.Path to kindling project root

Setup

kindling init

Synopsis: kindling init [flags]

Bootstrap a Kind cluster with the kindling operator, ingress controller, and in-cluster registry.

Steps: preflight checks → kind create cluster → switch kubectl context → install Traefik ingress + registry → load operator image → apply CRDs → deploy operator → wait for rollout.

Recommended resources:

WorkloadCPUsMemoryDisk
Small (1–3 services)48 GB30 GB
Medium (4–6 services)612 GB50 GB
Large (7+ services)8+16 GB80 GB

Flags:

FlagShortDefaultDescription
--skip-clusterfalseSkip Kind cluster creation (use existing)
--buildfalseBuild operator from source instead of pulling
--operator-imageghcr.io/kindling-sh/kindling-operator:latestOperator image to pull
--imageKind node image (e.g. kindest/node:v1.29.0)
--kubeconfigPath to write kubeconfig
--waitWait for control plane (e.g. 60s, 5m)
--retainfalseRetain nodes for debugging
--exposefalseStart HTTPS tunnel after bootstrap

Examples:

kindling init
kindling init --build
kindling init --expose
kindling init --image kindest/node:v1.29.0
kindling init --skip-cluster

kindling runners

Synopsis: kindling runners [flags]

Create a CI runner pool. Supports GitHub Actions (default) and GitLab CI.

Flags:

FlagShortDefaultDescription
--username-uCI platform username
--repo-rRepository (owner/repo or group/project)
--token-tPAT or runner registration token
--ci-providergithubgithub or gitlab

Examples:

kindling runners -u myuser -r myorg/myrepo -t ghp_xxxxx
kindling runners --ci-provider gitlab -u myuser -r mygroup/myproject -t glpat_xxxxx

kindling explain

Synopsis: kindling explain [topic]

Prints short, current guidance on kindling concepts and workflows (e.g. debugging/hot-reload, dependency auto-injection, Kaniko build constraints, secrets flow, staging graduation) — pulled on demand instead of injected into every coding-agent session. Run with no arguments to list topics.

kindling explain
kindling explain debugging

kindling analyze

Synopsis: kindling analyze [flags]

Check project readiness before generating a workflow. Detects Dockerfiles, dependencies (15 types), secrets, agent frameworks (LangChain, CrewAI, LangGraph, OpenAI Agents SDK, MCP), inter-service communication, and build context alignment.

Flags:

FlagShortDefaultDescription
--repo-path-r.Path to the repository
--verbose-vfalseShow additional detail

See Analyze for full reference.


kindling generate

Synopsis: kindling generate [flags]

AI-generate a CI workflow for any repository. Scans for Dockerfiles, dependencies, ports, health checks, Helm charts, Kustomize overlays, docker-compose files, .env templates, and agent frameworks. Produces a complete GitHub Actions or GitLab CI workflow.

Flags:

FlagShortDefaultDescription
--api-key-k— (required)GenAI API key
--repo-path-r.Path to the repository
--ai-provideropenaiopenai or anthropic
--modelautoModel name (default: o3 / claude-sonnet-4-20250514)
--output-oautoOutput path for workflow file
--dry-runfalsePrint to stdout instead of writing
--ingress-allfalseWire every service with an ingress
--no-helmfalseSkip Helm/Kustomize rendering
--ci-providergithubgithub or gitlab
--shared-depsComma-separated dependency types (e.g. redis,postgres) to mark shared: true across all detected services

Examples:

kindling generate -k sk-... -r .
kindling generate -k sk-... -r . --dry-run
kindling generate -k sk-ant-... -r . --ai-provider anthropic
kindling generate -k sk-... -r . --ci-provider gitlab
kindling generate -k sk-... -r . --ingress-all
kindling generate -k sk-... -r . --shared-deps redis,postgres

Develop

kindling deploy

Synopsis: kindling deploy -f <file>

Apply a DevStagingEnvironment from a YAML file (manual deploy).


kindling push

Synopsis: kindling push -s <service>

Rebuild and redeploy a single service via CI. Verifies workflow secrets and workflow file exist before triggering.


kindling sync

Synopsis: kindling sync [flags]

Live-sync local files into a running pod with language-aware hot reload. Automatic rollback on Ctrl+C.

Restart strategies (auto-detected):

StrategyRuntimesMechanism
wrapper + killNode.js, Python, Ruby, Perl, Lua, Julia, R, Elixir, Deno, BunPatch deployment, sync files, kill child to respawn
signal reloaduvicorn, gunicorn, Puma, Unicorn, Nginx, ApacheSIGHUP for zero-downtime reload
auto-reloadPHP, nodemonSync files, runtime re-reads automatically
local build + syncGo, Rust, Java, Kotlin, C#/.NET, C/C++, ZigCross-compile locally, sync binary, restart

Flags:

FlagShortDefaultDescription
--deployment-d— (required)Target deployment name
--src.Local source directory
--dest/appDestination inside container
--namespace-ndefaultKubernetes namespace
--restartfalseRestart app after each sync
--oncefalseSync once and exit
--containerContainer name (multi-container pods)
--excludeAdditional exclude patterns
--debounce500msDebounce interval
--languageautoOverride runtime detection
--build-cmdautoLocal build command for compiled languages
--build-outputautoPath to built artifact

Examples:

kindling sync -d my-api --restart
kindling sync -d my-api --restart --once
kindling sync -d orders --src ./services/orders --restart
kindling sync -d gateway --restart --language go
kindling sync -d frontend --src ./dist --dest /usr/share/nginx/html --restart

kindling debug

Synopsis: kindling debug -d <deployment> [flags]

Attach a VS Code debugger to a running deployment. Auto-detects runtime, injects debug agent, port-forwards, and writes launch.json.

Flags:

FlagShortDefaultDescription
--deployment-d— (required)Deployment name
--stopfalseStop an active debug session
--namespace-ndefaultKubernetes namespace
--portautoOverride local debug port
--no-launchfalseSkip writing launch.json

Supported runtimes:

RuntimeDebug toolDefault port
Pythondebugpy5678
Node.jsV8 Inspector9229
DenoV8 Inspector9229
BunBun Inspector6499
GoDelve2345
Rubyrdbg12345

Examples:

kindling debug -d my-api          # start debugging, then F5 in VS Code
kindling debug --stop -d my-api # stop and restore original deployment

See Debugging for language-specific details.


kindling dev

Synopsis: kindling dev -d <deployment> [flags]

Run a frontend dev server locally with full access to cluster APIs. For frontend deployments (nginx, caddy, httpd) where you want local hot reload instead of build+sync.

Steps: detect frontend → resolve source dir → port-forward backend APIs → detect OAuth/start tunnel → patch Vite/Next.js config → launch dev server.

Flags:

FlagShortDefaultDescription
--deployment-d— (required)Frontend deployment name
--namespace-ndefaultKubernetes namespace
--stopfalseStop the dev session

Examples:

kindling dev -d my-frontend       # start dev mode
kindling dev --stop -d my-frontend # stop

See Dev Mode for full documentation.


kindling load

Synopsis: kindling load -s <service> --context <path>

Build and load a container image directly into Kind (without CI).


kindling dashboard

Synopsis: kindling dashboard [--port 9090]

Launch the kindling web dashboard. Provides visual management for environments, sync, load, pods, logs, secrets, env vars, scaling, and tunnels.

Dashboard sections:

SectionCapabilities
SetupApp Designer, Analyze & Generate, Runners
DevelopEnvironments, API Explorer, Cluster Resources
StagingOverview, Deploy, Workloads, Network, TLS, Metrics

kindling expose

Synopsis: kindling expose [flags]

Create a public HTTPS tunnel to the cluster's ingress controller.

ProviderAccount required
cloudflaredNo (free quick tunnels)
ngrokYes (free tier available)

Flags:

FlagShortDefaultDescription
--tunnelauto-detectcloudflared or ngrok
--port80Local port to expose
--stopfalseStop tunnel and restore ingress
--serviceSpecific ingress to route to

kindling env

Synopsis: kindling env <subcommand> <deployment> [args]

Manage environment variables on running deployments.

SubcommandSynopsisDescription
setkindling env set <deploy> KEY=VALUE [...]Set environment variables
listkindling env list <deploy>List environment variables
unsetkindling env unset <deploy> KEY [...]Remove environment variables

kindling secrets

Synopsis: kindling secrets <subcommand>

Manage external credentials as Kubernetes Secrets with local backup.

SubcommandSynopsisDescription
setkindling secrets set <name> <value>Create/update Secret + local backup
listkindling secrets listList all kindling-managed secrets
deletekindling secrets delete <name>Remove from cluster and backup
restorekindling secrets restoreRe-create secrets from backup after cluster rebuild

kindling ingress

Synopsis: kindling ingress <subcommand>

Manage extra path -> service routes on a DevStagingEnvironment's managed Ingress (spec.ingress.routes) — additional paths merged onto the same host/Ingress alongside the DSE's primary route. Useful for a frontend that calls several backend services via same-origin path prefixes (/orgs, /auth, /billing, ...) under one shared host.

SubcommandSynopsisDescription
listkindling ingress list <dse>Show the primary route + all extra routes
add-routekindling ingress add-route <dse> --path P --service S --port NPatch a route onto the live Ingress
remove-routekindling ingress remove-route <dse> --path PRemove a route from the live Ingress
savekindling ingress save <dse> -f <file>Write the live extra routes into a DSE YAML file

Workflow: patch a route with add-route, confirm it works, then run save to persist the same routes into the DSE's YAML file so they're applied on every future deploy — not just this session's live patch.

kindling ingress add-route jeff-vincent-gateway --path /orders --service jeff-vincent-orders --port 5000
kindling ingress list jeff-vincent-gateway
kindling ingress save jeff-vincent-gateway -f dev-environment.yaml

kindling deps

Synopsis: kindling deps <subcommand>

Manage shared dependency instances (spec.dependencies[].shared) — see Shared dependencies. Shared instances aren't owned by any single DSE and aren't deleted automatically once unused, so use these to find and clean them up.

SubcommandSynopsisDescription
list-sharedkindling deps list-sharedList shared dependency instances and which DSEs reference them
prune-sharedkindling deps prune-sharedDelete shared instances no DSE references anymore
kindling deps list-shared
kindling deps prune-shared

kindling status

Synopsis: kindling status

Show cluster, operator, runner, and environment status. Includes crash diagnostics for unhealthy pods.


kindling logs

Synopsis: kindling logs [flags]

Tail the kindling controller logs.

Flags:

FlagShortDefaultDescription
--allfalseAll containers in the pod
--since5mDuration (e.g. 5m, 1h)
--follow-ftrueFollow output

Staging

kindling snapshot

Synopsis: kindling snapshot [flags]

Export a Helm chart or Kustomize overlay from the current cluster state, optionally push images to a container registry, and deploy to a staging cluster.

Steps: read all DSEs → strip actor prefix from names → generate chart with values.yaml (clean defaults) + values-live.yaml (dev values) → optionally push images via crane copy → optionally helm install on staging cluster.

With --deploy, unless --name/--namespace are set explicitly, both are derived from the current git branch (or --branch) via a stable slug — so concurrent branches deployed to the same shared staging cluster (e.g. multiple open PRs) never collide. Any DSE with Ingress enabled but no host set gets a branch-derived host too, via --staging-domain (result: <branch-slug>.staging.<domain>) — an explicit spec.ingress.host always wins over the derived one, and --deploy fails fast if neither is available rather than producing an unreachable environment.

Unless --tag is set explicitly, --registry pushes (with or without --deploy) auto-detect the next sequential <branch-slug>-N tag for the current branch, so concurrent branches pushing to the same shared registry get their own tag sequence instead of colliding on a single snapshot-N one.

With --render-prod-values (requires --registry in the same invocation), an additional values-prod.yaml is written alongside the chart: the same clean-defaults values every service already gets (TODO placeholders for anything credential-shaped, dependency connection strings included), except each service's image is pinned to the exact digest just pushed (registry/name@sha256:..., never a mutable tag) and KINDLING_ENV_PREFIX (default prod-, override with --prod-env-prefix) is added to every service's env. Kindling never generates, resolves, or stores an actual credential value here — the chart's Deployment template already wires every secret-backed env var to a secretKeyRef against a chart-managed Secret, identically for staging and production since both deploy the same chart; filling in the real value is a manual step (or whatever process your team already uses), by design, not something --render-prod-values does.

Combine --render-prod-values with --deploy in one call for the typical CI shape (a GH Actions job on pull_request): the production values are only written after the staging deploy actually succeeds, so a failed staging deploy never produces a values-prod.yaml — a later workflow step can use the file's mere existence as a pass/fail signal, then diff it against environments/production/values.yaml to flag whatever secrets the new build now needs before anyone merges.

Credential resolution (--deploy) is a single, unified pass, resolved once per distinct credential — never once per service, and never twice for the same one. In order: --creds-config (a committed YAML file mapping credential env var names to where their staging value actually lives — almost always fromEnv: SOME_ENV_VAR, a reference to an environment variable a CI job already populated from a GH Actions secret, never a literal value; plain non-secret values may use value: ... directly) always wins; anything the config file doesn't cover falls back automatically to the corresponding dev-cluster value, with no prompt — this is what makes every dev credential carry over to staging by default; a credential with no value anywhere (not in the config, and the dev-cluster value is itself empty) never fails the deploy — it's warned about immediately and, once the deploy succeeds, listed in MISSING_CREDENTIALS.md in the output directory for a later workflow step to check for and act on.

--non-interactive (also auto-enabled whenever stdin isn't a TTY, e.g. any GH Actions runner) makes the whole command safe to run unattended: no huh form is ever shown, for credentials, registry auth, or Ingress selection. Registry auth comes from --registry-username/KINDLING_REGISTRY_USERNAME and the KINDLING_REGISTRY_PASSWORD env var — deliberately no --registry-password flag, since a password passed as a plain CLI argument would be visible via ps/shell history. --ingress-services (a comma-separated service list, or an explicitly-empty string to disable Ingress for all) replaces the interactive multi-select; when omitted in non-interactive mode, it defaults to whatever was already enabled in the dev cluster.

Flags:

FlagShortDefaultDescription
--format-fhelmhelm or kustomize
--output-o./kindling-snapshotOutput directory
--name-nkindling-snapshot (or branch slug with --deploy)Chart/project name
--registry-rContainer registry (e.g. ghcr.io/myorg)
--tag-tnext sequential <branch-slug>-N (or snapshot-N outside a git branch context)Image tag
--deployfalseDeploy after generating chart
--contextKubeconfig context for staging cluster
--namespacedefault (or branch slug with --deploy)Namespace to deploy into
--branchcurrent git branchGit branch to derive the staging name/namespace/Ingress host/image tag from (used with --deploy or --registry)
--staging-domainBase domain for branch-derived Ingress hosts — result is <branch-slug>.staging.<domain>, e.g. subnode1.xyz (required for --deploy if the DSE doesn't already set an Ingress host)
--render-prod-valuesfalseWrite a values-prod.yaml with the promoted image digest pinned in, alongside the chart (requires --registry)
--prod-env-prefixprod-KINDLING_ENV_PREFIX value injected into every service's env when using --render-prod-values
--creds-configPath to a YAML file mapping credential env vars to staging values (fromEnv/value) — safe to commit, no literal secrets when using fromEnv
--non-interactivefalseNever prompt (fail fast instead if a required value can't be resolved from flags/env/config) — for CI; auto-enabled when stdin isn't a TTY
--registry-usernameRegistry username (falls back to KINDLING_REGISTRY_USERNAME; password must come from KINDLING_REGISTRY_PASSWORD or an interactive prompt, never a flag)
--ingress-servicesComma-separated list of services to enable public Ingress for (pass an empty string to disable Ingress for all) — skips the interactive prompt when set

Examples:

# Generate only
kindling snapshot # Helm chart in ./kindling-snapshot/
kindling snapshot --format kustomize # Kustomize overlay
kindling snapshot -o ./my-chart # custom output directory

# Push images + deploy to staging
kindling snapshot -r ghcr.io/myorg --deploy --context do-staging
kindling snapshot -r ghcr.io/myorg -t v1.2.0 --deploy --context do-staging --namespace staging

# PR branch → its own name/namespace-scoped staging environment
# (feature/checkout-retry -> name/namespace "feature-checkout-retry")
kindling snapshot -r ghcr.io/myorg --deploy --context do-staging

# ...with a branch-derived, resolvable Ingress host too
# (-> feature-checkout-retry.staging.example.com)
kindling snapshot -r ghcr.io/myorg --deploy --context do-staging --staging-domain example.com

# Push images and also write values-prod.yaml, pinned to the pushed digest
# (no deploy — kindling never touches a production cluster or credential)
kindling snapshot -r ghcr.io/myorg --render-prod-values

# Typical CI shape: deploy to staging, then (only if that succeeded)
# write values-prod.yaml for a later workflow step to diff/review
kindling snapshot -r ghcr.io/myorg --deploy --context do-staging --render-prod-values

# Fully unattended, from a GH Actions job (KINDLING_REGISTRY_USERNAME/
# KINDLING_REGISTRY_PASSWORD populated from ${{ secrets.* }}) -- no prompt
# is ever shown, for credentials, registry auth, or Ingress selection
kindling snapshot -r ghcr.io/myorg --deploy --context do-staging \
--non-interactive --creds-config deploy/staging-credentials.yaml \
--ingress-services frontend,api

Manual usage:

helm template my-app ./kindling-snapshot -f values-live.yaml
helm install my-app ./kindling-snapshot \
--set gateway.env.DATABASE_URL=postgres://staging-host:5432/mydb

kindling staging tls

Synopsis: kindling staging tls [flags]

Configure TLS with cert-manager for staging Ingress resources. Installs cert-manager, creates a Let's Encrypt ClusterIssuer, and optionally patches a DSE YAML to enable TLS.

Flags:

FlagShortDefaultDescription
--context— (required)Kubeconfig context for staging cluster
--domain— (required)Domain for TLS certificate
--email— (required)Email for Let's Encrypt registration
--issuerletsencrypt-prodClusterIssuer name
--stagingfalseUse Let's Encrypt staging server
--file-fDSE YAML to patch with TLS config
--ingress-classtraefikIngressClass for ACME solver

Examples:

kindling staging tls --context my-staging --domain app.example.com --email admin@example.com
kindling staging tls --context my-staging --domain app.example.com --staging
kindling staging tls --context my-staging --domain app.example.com -f dev-environment.yaml

Lifecycle

kindling reset

Synopsis: kindling reset [-y]

Remove the runner pool to point at a new repo. Leaves the cluster intact.


kindling destroy

Synopsis: kindling destroy [-y]

Delete the Kind cluster and all resources.


kindling version

Synopsis: kindling version

Print the CLI version.


Dependency Auto-Injection

When a dependency is declared in spec.dependencies[], the operator auto-injects the connection URL:

DependencyInjected env var
postgresDATABASE_URL
redisREDIS_URL
mysqlDATABASE_URL
mongodbMONGO_URL
rabbitmqAMQP_URL
minioS3_ENDPOINT
elasticsearchELASTICSEARCH_URL
kafkaKAFKA_BROKER_URL
natsNATS_URL
memcachedMEMCACHED_URL
cassandraCASSANDRA_URL
consulCONSUL_URL
vaultVAULT_ADDR
influxdbINFLUXDB_URL
jaegerJAEGER_URL

Do not duplicate these in spec.env[] — they are injected automatically.


Typical Workflow

# ── SETUP ────────────────────────────────────────
kindling init
kindling runners -u alice -r acme/myapp -t ghp_xxxxx
kindling analyze
kindling generate -k sk-... -r .
kindling secrets set STRIPE_KEY sk_live_...

# ── DEVELOP ──────────────────────────────────────
git push origin main # outer loop: build + deploy
kindling status # verify deployment
kindling sync -d alice-myapp --restart # inner loop: live sync
kindling debug -d alice-myapp # attach debugger
kindling dev -d alice-frontend # frontend hot reload
kindling dashboard # visual control plane
kindling env set alice-myapp LOG_LEVEL=debug
kindling push -s alice-myapp # rebuild one service
kindling expose # public URL for OAuth

# ── PRODUCTION ───────────────────────────────────
kindling snapshot -r ghcr.io/myorg --deploy --context my-staging
kindling staging tls --context my-staging --domain app.example.com --email admin@example.com

# ── LIFECYCLE ────────────────────────────────────
kindling reset # switch repos
kindling destroy -y # tear down