kindling takes a project from first commit to a production-ready Helm chart, in four stages: dev locally (with best-practice guardrails built in), CI-first from the very first push, graduate to a shared staging cluster with zero collisions between branches, then hand off a production-ready chart at the git boundary — kindling never touches production itself.
kindling analyze
(readiness check — Dockerfiles, secrets, health checks, best-practice guardrails)
│
▼
kindling generate
(AI-writes your CI workflow — CI-first from commit 1, zero cloud CI minutes)
│
▼
┌─────────────────── Dev Loop (every push runs real CI) ─────────┐
│ │
│ push → build (Kaniko) → deploy (outer loop) │
│ ↕ │
│ edit → sync → reload (inner loop, sub-second) │
│ ↕ │
│ expose → test OAuth / webhooks │
│ ↕ │
│ add services → debug → iterate │
│ │
└────────────────────────────────────────────────────────────────┘
│
▼
kindling snapshot --deploy
(graduate to a shared, multi-tenant staging cluster — branch-scoped
name/namespace/Ingress so concurrent branches never collide; fully
non-interactive when run from CI)
│
▼
kindling snapshot --render-prod-values
(production-ready Helm chart + values-prod.yaml, pinned image
digests — hand off to your GitOps controller at the git boundary)
Zero cloud CI minutes. Immediate iteration. Full Kubernetes everything.
kindling adds almost nothing to your machine. The entire operator is a 14 MB static binary that runs as a single pod requesting 15m CPU and 128 MB RAM. Everything else in the cluster is your application. A single-service setup runs comfortably under 1 GB total.
| Component | Footprint |
|---|---|
| CLI binary | 14 MB, single static Go binary |
| Operator pod | 15m CPU / 128 Mi RAM (2 containers) |
| In-cluster registry | ~30 Mi RAM |
| Ingress controller | ~90 Mi RAM |
| kindling total | < 250 Mi RAM — everything else is your app |
Before generating a workflow, kindling analyze scans your repo and tells you exactly what's ready and what needs attention:
kindling analyze kindling analyze — /path/to/your-app
✅ Git repository initialized
✅ Has commits
✅ Remote: https://github.com/you/your-app.git
✅ Found 2 Dockerfile(s)
✅ Found 3 dependency manifest(s)
ℹ️ Primary language: Python
ℹ️ Multi-agent architecture detected
ℹ️ Agent frameworks: LangChain
✅ Secret OPENAI_API_KEY exists in cluster
✅ Kind cluster 'dev' is running
✅ Ready for 'kindling generate'
Analyze checks: git state, Dockerfiles, Kaniko compatibility, build context paths, dependencies, agent architecture (LangChain, CrewAI, AutoGen, etc.), secrets, project structure, and cluster health.
Point kindling generate at your repo. It scans everything — Dockerfiles, docker-compose, Helm charts, source code — and uses AI to produce a complete CI workflow:
kindling generate -k <api-key> -r /path/to/your-appIt detects services, languages, dependencies, ports, health checks, external credentials, OAuth patterns, agent frameworks, MCP servers, worker processes, and inter-service calls. Supports OpenAI (o3) and Anthropic (claude-sonnet).
The output is .github/workflows/dev-deploy.yml (or .gitlab-ci.yml).
The dev loop has two gears: the outer loop (CI-driven) and the inner loop (sub-second live sync).
Every git push triggers a real CI pipeline on your laptop. A self-hosted runner builds containers via Kaniko, pushes to an in-cluster registry, and the kindling operator deploys a complete staging environment.
kindling push -s api,worker # push + selective rebuild
kindling status # see what's runningOnce deployed, skip CI entirely. Edit a file, sync it into the running container, see the result in under a second:
kindling sync -d my-api --restart # watch + auto-restartThe runtime is auto-detected from the container's process:
| Strategy | Runtimes | What happens |
|---|---|---|
| Signal reload | uvicorn, gunicorn, Puma, Nginx | SIGHUP for zero-downtime reload |
| Wrapper + kill | Node.js, Python, Ruby, Deno, Bun | Restart-loop wrapper respawns process |
| Local build + sync | Go, Rust, Java, C# | Cross-compiles locally, syncs binary |
| Frontend build | React, Vue, Angular, Svelte | Builds locally, syncs into nginx |
| Auto-reload | PHP, nodemon | Just syncs — runtime picks them up |
When you stop syncing, the deployment automatically rolls back to its original state.
kindling dashboard # open at localhost:9090View environments, pods, logs, events. Click Sync or Load on any service. The topology map shows your full service graph.
kindling expose # HTTPS tunnel, one commandkindling env set my-api LOG_LEVEL=debug # change env vars live
kindling secrets set STRIPE_KEY sk_... # manage credentials
kindling push -s new-service # add and deploy a new service
kindling debug -d my-api # attach debugger — F5 in VS Code
kindling dev -d my-frontend # frontend hot reload + cluster APIsOnce your app works in the dev loop, kindling snapshot reads every
DevStagingEnvironment in your cluster and generates a staging-ready
Helm chart (or Kustomize overlay). With --registry it copies images
out of the in-cluster registry via crane — no Docker daemon needed.
With --deploy, it pushes that chart straight to any real Kubernetes
cluster you point it at:
kindling snapshot -r ghcr.io/myorg --deploy --context stagingMulti-tenant by default — --name/--namespace/Ingress host are
all derived from the current git branch, so concurrent branches
deployed to the same shared staging cluster never collide:
# PR branch → its own name-scoped staging environment, no collisions
kindling snapshot -r ghcr.io/myorg --deploy --context staging \
--staging-domain example.comFully non-interactive from CI — no form ever blocks on stdin.
Registry auth and staging credentials resolve from flags, env vars, or
a committed --creds-config file (never a literal secret in the repo);
anything genuinely unresolvable is warned about and written to
MISSING_CREDENTIALS.md — it never fails the deploy:
kindling snapshot -r ghcr.io/myorg --deploy --context staging \
--non-interactive --creds-config deploy/staging-credentials.yamlA CIRunnerPool with enableSnapshotDeploy: true runs this same
command from the self-hosted runner that already builds and deploys
your dev environment — the whole graduation step happens inside a GH
Actions job, no laptop required (see
kindling-snapshot-deploy).
--render-prod-values (combined with --deploy, only runs after the
staging deploy actually succeeds) writes values-prod.yaml alongside
the chart — the same clean, credential-free values every export
produces, plus each service's image pinned to the exact digest just
pushed:
kindling snapshot -r ghcr.io/myorg --deploy --context staging \
--render-prod-valueskindling never holds a production credential and never calls a production cluster's API server. The resulting chart + values file is meant to be committed and picked up by whatever GitOps controller (Argo CD, Flux, etc.) already owns your production deploys, at the git boundary — not driven by kindling itself.
# Install
brew install kindling-sh/tap/kindling
# Bootstrap local cluster
kindling init
# Register a CI runner (GitHub or GitLab)
kindling runners -u <user> -r <owner/repo> -t <pat>
# Check your project
kindling analyze
# AI-generate a CI workflow
kindling generate -k <api-key> -r /path/to/app
# Push → build → deploy
git push origin main
# Open the dashboard
kindling dashboard
# Start live sync on a service
kindling sync -d <user>-my-app --restart
# Graduate to a shared staging cluster (from your laptop or CI)
kindling snapshot -r ghcr.io/myorg --deploy --context stagingYour AI coding agent (Copilot, Claude Code, Cursor, Windsurf) is a
legitimate place to run kindling. kindling --help and kindling explain <topic> teach the agent your dev environment — CLI commands,
dependencies, secrets, build protocol, hot-reload debugging — on
demand, not injected into every session. A few tokens in, full dev
workflow out.
kindling explain # list topics
kindling explain debugging # hot-reload / sync workflow
kindling explain dependencies # auto-injection env varsThe agent knows every command. You describe what you want, the agent
suggests kindling debug, kindling sync, or kindling dev, you
run it — the heavy lifting happens outside the agent loop in the
cluster.
Declare dependencies in your workflow. The operator provisions them and injects connection URLs:
| Dependency | Injected env var |
|---|---|
| postgres | DATABASE_URL |
| redis | REDIS_URL |
| mysql | DATABASE_URL |
| mongodb | MONGO_URL |
| rabbitmq | AMQP_URL |
| kafka | KAFKA_BROKER_URL |
| elasticsearch | ELASTICSEARCH_URL |
| minio | S3_ENDPOINT |
| nats | NATS_URL |
| memcached | MEMCACHED_URL |
| cassandra | CASSANDRA_URL |
| consul | CONSUL_HTTP_ADDR |
| vault | VAULT_ADDR |
| influxdb | INFLUXDB_URL |
| jaeger | JAEGER_ENDPOINT |
kindling secrets set STRIPE_KEY sk_live_abc123 # store
kindling secrets list # list
kindling secrets restore # restore after cluster rebuildSecrets are stored as Kubernetes Secrets with automatic local backup. They survive cluster rebuilds.
The operator manages two CRDs in the apps.example.com/v1alpha1 group:
Declares a self-hosted CI runner pool. Supports GitHub Actions and GitLab CI.
apiVersion: apps.example.com/v1alpha1
kind: CIRunnerPool
metadata:
name: jeff-runner-pool
spec:
ciProvider: github
githubUsername: "jeff-vincent"
repository: "jeff-vincent/demo-kindling"
tokenSecretRef:
name: github-runner-token
replicas: 1Declares a complete staging environment: Deployment, Service, Ingress, and dependencies.
apiVersion: apps.example.com/v1alpha1
kind: DevStagingEnvironment
metadata:
name: jeff-dev
spec:
deployment:
image: registry:5000/myapp:jeff-abc123
replicas: 1
port: 8080
healthCheck:
path: /healthz
service:
port: 8080
ingress:
enabled: true
host: jeff-dev.localhost
ingressClassName: traefik
dependencies:
- type: postgres
version: "16"
- type: redisBuilds a container image via the Kaniko sidecar:
- uses: kindling-sh/kindling/.github/actions/kindling-build@main
with:
name: my-app
context: ${{ github.workspace }}
image: "registry:5000/my-app:${{ env.TAG }}"Generates and applies a DevStagingEnvironment CR:
- uses: kindling-sh/kindling/.github/actions/kindling-deploy@main
with:
name: "${{ github.actor }}-my-app"
image: "registry:5000/my-app:${{ env.TAG }}"
port: "8080"
ingress-host: "${{ github.actor }}-my-app.localhost"
dependencies: |
- type: postgres
version: "16"Runs kindling snapshot --deploy from a CIRunnerPool with
enableSnapshotDeploy: true — image copy to a real registry plus a
Helm install against a separate, shared staging cluster, entirely from
the self-hosted runner (no laptop required):
- uses: kindling-sh/kindling/.github/actions/kindling-snapshot-deploy@main
with:
name: checkout-staging
registry: ghcr.io/myorg
staging-context: staging
staging-kubeconfig: ${{ secrets.STAGING_KUBECONFIG }}
extra-args: "--creds-config deploy/staging-credentials.yaml --non-interactive"A Go web server with Postgres + Redis. → examples/sample-app/
Orders, Inventory, Gateway, and a React UI with Postgres, MongoDB, and Redis. → examples/microservices/
Go API + React dashboard with Postgres, Redis, Elasticsearch, Kafka, and Vault. → examples/platform-api/
brew install kindling-sh/tap/kindlingDownload from GitHub Releases.
macOS Gatekeeper note: If you see "Apple could not verify kindling is free of malware", run:
sudo xattr -d com.apple.quarantine /usr/local/bin/kindling
git clone https://github.com/kindling-sh/kindling.git
cd kindling && make cli
sudo mv bin/kindling /usr/local/bin/| Tool | Version |
|---|---|
| Docker | 24+ |
| Kind | 0.20+ |
| kubectl | 1.28+ |
| Workload | CPUs | Memory | Disk | kindling overhead |
|---|---|---|---|---|
| Minimal (1 service, no deps) | 2 | 4 GB | 20 GB | < 250 Mi |
| Small (1–3 services) | 4 | 8 GB | 30 GB | < 250 Mi |
| Medium (4–6 services) | 6 | 12 GB | 50 GB | < 250 Mi |
| Large (7+ services) | 8+ | 16 GB | 80 GB | < 250 Mi |
kindling's own footprint stays constant regardless of workload size. The memory growth comes from your services and dependencies.
| Command | Description |
|---|---|
| Setup | |
kindling init |
Bootstrap Kind cluster + operator + registry + ingress |
kindling runners |
Register a CI runner (GitHub Actions or GitLab CI) |
kindling explain |
On-demand kindling concepts/workflow guidance |
| Onboarding | |
kindling analyze |
Check project readiness — git, Dockerfiles, secrets, cluster |
kindling generate |
AI-generate a CI workflow |
| Dev Loop | |
kindling push |
Git push with selective service rebuild |
kindling sync |
Live-sync files + hot reload |
kindling dashboard |
Web dashboard with topology map |
kindling deploy |
Apply a DevStagingEnvironment from YAML |
kindling load |
Build + load image without CI |
kindling expose |
Public HTTPS tunnel for OAuth/webhooks |
| Operations | |
kindling status |
Cluster and environment status |
kindling logs |
Tail operator logs |
kindling secrets |
Manage external credentials |
kindling env |
Set/list/unset env vars on deployments |
| Staging & Production Handoff | |
kindling snapshot |
Export a Helm chart/Kustomize overlay; --deploy graduates to a shared staging cluster (non-interactive-safe for CI); --render-prod-values writes a GitOps-ready production chart |
kindling staging tls |
Wildcard DNS-01 TLS for a shared staging cluster |
| Lifecycle | |
kindling reset |
Remove runner pool (keep cluster) |
kindling destroy |
Tear down the cluster |
- GitHub Actions + GitLab CI runners on localhost
- 15 auto-provisioned dependency types
- Kaniko container builds (no Docker daemon)
- AI workflow generation with agent architecture awareness
-
kindling analyze— deterministic project readiness checking -
kindling sync— live file sync with 30+ language-aware restart strategies -
kindling dashboard— web UI with topology map, sync/load, runtime detection -
kindling snapshot --deploy— graduate to a shared, multi-tenant staging cluster (branch-scoped naming, non-interactive-safe for CI) -
kindling snapshot --render-prod-values— GitOps-ready production Helm chart with pinned image digests -
CIRunnerPoolsnapshot-deploy sidecar — runkindling snapshot --deployentirely from a self-hosted GH Actions runner, no laptop required - Wildcard DNS-01 TLS for shared staging clusters
-
kindling explain— on-demand kindling concepts/workflow guidance for coding agents - Secrets management with local backup across cluster rebuilds
- Public HTTPS tunnels for OAuth
- Topology map: drag-and-drop service/dependency editor
- Interactive service health resolution in dashboard
Contributions welcome! Please open an issue to discuss your idea before submitting a PR.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run
make test - Open a Pull Request
Apache License 2.0 — see LICENSE for full text.