DEV Community

Jeff Vincent
Jeff Vincent

Posted on • Edited on

Run Real K8s CI on your Laptop with Kindling

TLDR: Kindling wires your GitHub repo to a local Kubernetes cluster. Every git push builds and deploys your app with real databases and services. No cloud CI minutes, no waiting. AI generates your workflow. A built-in dashboard gives you full cluster visibility.

Kindling is a Kubernetes operator that runs in a local KinD cluster. Point it at your repo, and it handles builds and deployments locally while you develop.

It spins up a GitHub Actions runner pool inside your cluster. When you push code, the runner builds your containers using Kaniko and deploys everything to the cluster. Your app gets real Postgres, Redis, Kafka, or whatever you need — already configured and wired up.

Since the initial release, the CLI has grown quite a bit. Here's what's new.

The operator supports 15 dependency types:

Type Default Image Port Injected Env Var Notes
postgres postgres:16 5432 DATABASE_URL Auto-creates devdb with user devuser
redis redis 6379 REDIS_URL Stateless, no persistence
mysql mysql 3306 DATABASE_URL Auto-creates devdb with user devuser
mongodb mongo 27017 MONGO_URL Root user devuser
rabbitmq rabbitmq:3-management 5672 AMQP_URL Includes management UI on port 15672
minio minio/minio 9000 S3_ENDPOINT Also injects S3_ACCESS_KEY + S3_SECRET_KEY
elasticsearch docker.elastic.co/elasticsearch/elasticsearch:8.12.0 9200 ELASTICSEARCH_URL Single-node, security disabled
kafka apache/kafka 9092 KAFKA_BROKER_URL KRaft mode (no ZooKeeper)
nats nats 4222 NATS_URL Lightweight messaging
memcached memcached 11211 MEMCACHED_URL In-memory cache
cassandra cassandra 9042 CASSANDRA_URL Single-node dev cluster
consul hashicorp/consul 8500 CONSUL_HTTP_ADDR Dev-mode agent
vault hashicorp/vault 8200 VAULT_ADDR Dev mode, also injects VAULT_TOKEN
influxdb influxdb 8086 INFLUXDB_URL Also injects INFLUXDB_ORG + INFLUXDB_BUCKET
jaeger jaegertracing/all-in-one 16686 JAEGER_ENDPOINT Also injects OTEL_EXPORTER_OTLP_ENDPOINT

AI-powered workflow generation

kindling generate scans your repo and calls an LLM to produce a complete GitHub Actions workflow. It walks your project tree, reads Dockerfiles, dependency manifests, and source files, and sends the right context to the model. It recognizes 20+ ecosystems — Go, Node, Python, Rust, Java, Ruby, PHP, Elixir, .NET, and more.

kindling generate -k <your-api-key>
Enter fullscreen mode Exit fullscreen mode

It also detects external credential references and OAuth/OIDC patterns in your code. If it finds them, it suggests follow-up commands like kindling secrets set and kindling expose. Supports both OpenAI and Anthropic models via the --provider flag.

The generated workflow drops into .github/workflows/dev-deploy.yml, ready to go on your next push.

Embedded dashboard

kindling dashboard launches a local web UI embedded directly in the CLI binary. No extra installs, no Docker image — just run the command and open http://localhost:9090.

kindling dashboard
Enter fullscreen mode Exit fullscreen mode

The dashboard gives you full cluster visibility: nodes, deployments, pods, services, ingresses, secrets, events, DSEs, runner pools, and RBAC resources. It also exposes action endpoints — you can deploy, manage secrets, create runners, set env vars, expose tunnels, restart or scale deployments, and apply raw YAML, all from the browser.

There's a command palette (Cmd+K) for quick actions and a sidebar with real-time tunnel status when you have a public URL active.

Public HTTPS tunnels

kindling expose creates a secure tunnel from a public URL to your cluster's ingress controller. Useful for OAuth callbacks, webhook testing, or showing someone your work without deploying to the cloud.

kindling expose
Enter fullscreen mode Exit fullscreen mode

It runs cloudflared (or ngrok) in the background and patches your ingress routes to use the tunnel hostname. When you're done, kindling expose --stop tears it down and restores the original ingress config. The tunnel URL is also stored in a ConfigMap so the deploy action can auto-discover it during CI.

Secrets management

kindling secrets manages external service credentials as Kubernetes Secrets. API keys, tokens, connection strings — set them once and they're available to your deployments.

kindling secrets set STRIPE_KEY sk_test_abc123
kindling secrets list
Enter fullscreen mode Exit fullscreen mode

Credentials are also saved to .kindling/secrets.yaml locally, so kindling secrets restore can re-create them after a cluster rebuild.

Live env var management

kindling env sets or removes environment variables on a running deployment without redeploying. Changes take effect immediately via a rolling restart.

kindling env set my-app DEBUG=true LOG_LEVEL=verbose
kindling env unset my-app DEBUG
Enter fullscreen mode Exit fullscreen mode

Selective rebuilds

kindling push wraps git push with an optional service filter. Tag your push so CI only rebuilds the services you changed instead of the full pipeline.

kindling push --service ui --service gateway
Enter fullscreen mode Exit fullscreen mode

It amends the HEAD commit with a [kindling:ui,gateway] marker that CI parses. Omit --service to rebuild everything as usual.

Other CLI commands

  • kindling status — Full environment overview: cluster health, operator, registry, runner pools, DSEs, deployments, ingress routes, and unhealthy pod logs. Color-coded, no flags needed.
  • kindling logs — Streams operator logs. --all for all containers, --since 10m to adjust the window.
  • kindling reset — Removes the runner pool and its token secret without touching the cluster or your deployments. Good for switching repos.
  • kindling destroy — Tears down the entire Kind cluster.

Setup

You need Docker, Kind, and kubectl installed.

1. Install the CLI

Homebrew (recommended — macOS and Linux)

brew install kindling-sh/tap/kindling
Enter fullscreen mode Exit fullscreen mode

This installs the latest release and pulls in Kind and kubectl as dependencies.

Pre-built binaries

Download the latest release for your platform from GitHub Releases:

# macOS (Apple Silicon)
curl -Lo kindling.tar.gz https://github.com/kindling-sh/kindling/releases/latest/download/kindling_$(curl -s https://api.github.com/repos/kindling-sh/kindling/releases/latest | grep tag_name | cut -d '"' -f4 | sed 's/^v//')_darwin_arm64.tar.gz
tar xzf kindling.tar.gz
sudo mv kindling /usr/local/bin/

# macOS (Intel)
curl -Lo kindling.tar.gz https://github.com/kindling-sh/kindling/releases/latest/download/kindling_$(curl -s https://api.github.com/repos/kindling-sh/kindling/releases/latest | grep tag_name | cut -d '"' -f4 | sed 's/^v//')_darwin_amd64.tar.gz
tar xzf kindling.tar.gz
sudo mv kindling /usr/local/bin/

# Linux (amd64)
curl -Lo kindling.tar.gz https://github.com/kindling-sh/kindling/releases/latest/download/kindling_$(curl -s https://api.github.com/repos/kindling-sh/kindling/releases/latest | grep tag_name | cut -d '"' -f4 | sed 's/^v//')_linux_amd64.tar.gz
tar xzf kindling.tar.gz
sudo mv kindling /usr/local/bin/
Enter fullscreen mode Exit fullscreen mode

macOS Gatekeeper note: If you see "Apple could not verify kindling is free of malware", clear the quarantine flag:

sudo xattr -d com.apple.quarantine /usr/local/bin/kindling

Build from source

Requires Go 1.25+:

git clone https://github.com/kindling-sh/kindling.git && cd kindling
make cli
sudo mv bin/kindling /usr/local/bin/
Enter fullscreen mode Exit fullscreen mode

2. Bootstrap the cluster

kindling init
Enter fullscreen mode Exit fullscreen mode

This creates a KinD cluster, installs an in-cluster registry, sets up ingress-nginx, and deploys the operator. Takes about a minute.

3. Create a GitHub repo

You need a repo on GitHub before you can register a runner to it. The easiest way is with the GitHub CLI:

gh repo create my-app --public --clone && cd my-app
Enter fullscreen mode Exit fullscreen mode

If you don't have gh installed, create the repo on github.com/new, then clone it:

git clone git@github.com:<you>/my-app.git && cd my-app
Enter fullscreen mode Exit fullscreen mode

4. Register your GitHub runner

Note: the following -r should be in the format of <your-gh-user-name>/my-app if you followed the above exactly.

kindling runners -u <github-user> -r <owner/repo> -t <your-pat>
Enter fullscreen mode Exit fullscreen mode

You need a GitHub PAT with repo scope. The runner registers with GitHub and starts polling for jobs.

5. Generate your workflow

You can write the GitHub Actions workflow by hand, or let the AI generate it:

kindling generate -k <your-openai-or-anthropic-key>
Enter fullscreen mode Exit fullscreen mode

This scans your project and writes .github/workflows/dev-deploy.yml. Review it, tweak if needed, and move on.

6. Deploy the sample app

cp -r ~/kindling/examples/microservices/* .
cp -r ~/kindling/examples/microservices/.github .

git add -A && git commit -m "initial deploy" && git push
Enter fullscreen mode Exit fullscreen mode

7. Watch it deploy

Check the Actions tab in GitHub or watch pods locally:

kubectl get pods -w
Enter fullscreen mode Exit fullscreen mode

Your app, Postgres, and Redis will spin up and start running.

8. Access your app

Navigate in your browser to:

http://<your-gh-username>-ui.localhost
Enter fullscreen mode Exit fullscreen mode

9. Make changes

# Edit code
git add -A && git commit -m "update" && git push
Enter fullscreen mode Exit fullscreen mode

Fresh build and deploy in seconds.

How it works

The GitHub workflow uses two actions:

kindling-build builds your image with Kaniko and pushes to the in-cluster registry.

kindling-deploy generates a DevStagingEnvironment resource. The operator reads it and creates your Deployment, Service, Ingress, and backing services.

Here's a sample app workflow:

- name: Build image
  uses: kindling-sh/kindling/.github/actions/kindling-build@main
  with:
    name: sample-app
    context: ${{ github.workspace }}
    image: "registry:5000/sample-app:${{ env.TAG }}"

- name: Deploy
  uses: kindling-sh/kindling/.github/actions/kindling-deploy@main
  with:
    name: "${{ github.actor }}-sample-app"
    image: "registry:5000/sample-app:${{ env.TAG }}"
    port: "8080"
    ingress-host: "${{ github.actor }}-sample-app.localhost"
    dependencies: |
      - type: postgres
        version: "16"
      - type: redis
Enter fullscreen mode Exit fullscreen mode

What's next

  • Multi-cluster support
  • Built-in observability
  • Helm chart integration
  • Change detection at the operator level

Contributing

Contributions welcome. Open an issue or PR on the GitHub repo. Apache 2.0 licensed.

Conclusion

Kindling gives you local CI speed with real infrastructure. Push code, get a deployed app with real databases in seconds. Generate your workflow with AI, manage secrets and env vars without redeploying, expose your app publicly for OAuth testing, and monitor everything from a built-in dashboard. If you're tired of waiting for cloud CI or want tighter feedback loops, give it a try.

Star the repo if you find it useful.

Top comments (0)