Local dev environment,
up in minutes.

Define your apps in one file. Kustron handles the rest: local cluster, registry, build, deploy. Your kubectl context is never touched.

$ npm install -g kustron && kustron doctor
See all features & examples → ▶ Watch the fullstack demo

Watch the full demo: bringing the environment up with apps on it, live watch included.

One kustron-env.yaml, one command → a CRUD API over a Redis-compatible KV store built from source → live rebuild on an edit → a Helm-charted RabbitMQ + order stream → a public GitHub repo deployed as-is → clean env destroy. Hover the video for the full-screen button, or double-click it.


A real stack to keep developing on, up in four commands.

Kustron provisions a local container-native cluster with k3d under the hood — you never touch it. You define what to run in one file; it builds, deploys, and watches.

Step 01

Initialise

Create a kustron-env.yaml in your project folder, pre-filled with your app name.

$ kustron env init
Step 02

Edit the file

Set ports, add more apps, configure env vars. Or just set the port and move on.

kustron-env.yaml
Step 03

Bring it up

One command spins up the cluster, builds images, and deploys everything.

$ kustron env up
Step 04

Iterate

Add apps, change config, redeploy. The file is the source of truth.

$ kustron env reload

Where it takes an hour, Kustron takes one command.

Six situations where the environment is the whole job.

Full-stack local development

Frontend, API, database, cache, workers — everything running together and reachable by name. Each app can also get its own namespace with a one-line namespace: override. env watch auto-redeploys on every save.

Onboarding new team members

The kustron-env.yaml is the environment documentation. Clone the repo, run env up, and you're productive in minutes instead of hours.

Reproducible environments anywhere

The same file gives you an identical stack on your laptop, a teammate's machine, or a $6/month cloud VM. No "works on my machine."

Production parity before shipping

Test Helm charts, private registry auth, deploy ordering with dependsOn, HPA autoscaling, and namespace isolation locally.

Ephemeral sandboxes and demos

Spin up an isolated stack for a spike, a customer demo, or integration testing. env destroy when done and nothing lingers.

Safe experimentation

Kustron never calls kubectl config use-context. Every command uses --context=k3d-<clusterName>, so your production clusters stay untouched.


Your whole environment in one file.

Apps find each other by name. Exposed apps are reachable at localhost:<nodePort>.

kustron-env.yaml
          
          config:
            namespace: kustron-env        # default namespace; each app can override with `namespace:`

          apps:
            # Build from local source or git repo
            - name: api
              source: ./services/api      # or: git@github.com:org/repo.git
              port: 3000
              exposed: true               # reachable at localhost:<nodePort>
              ha: true                    # min 2 replicas, autoscales to 5
              env:
                NODE_ENV: production
                DB_HOST: postgres         # resolves to the postgres service by name

            # Run an existing container image
            - name: postgres
              image: postgres:15
              port: 5432
              env:
                POSTGRES_PASSWORD: secret
                POSTGRES_DB: myapp

            # Deploy a Helm chart
            - name: prometheus
              helm:
                chart: kube-prometheus-stack
                repo: https://prometheus-community.github.io/helm-charts
                version: "45.0.0"
                values:
                  grafana:
                    enabled: true
          
        

Your repo, plus the infra it needs.

Start inside a source repo with a Dockerfile. Add a local DynamoDB, an S3-compatible store, and a cache, then bring it all up.

terminal
          
          cd my-api                                  # your repo, with a Dockerfile
          kustron env init                           # creates kustron-env.yaml

          kustron apps add --name local-ddb  --image amazon/dynamodb-local:latest --port 8000 --healthcheck tcp
          kustron apps add --name local-s3   --image luofuxiang/local-s3 --port 80
          kustron apps add --name kivo       --image ghcr.io/itsmunim/kivo:v1.5.0 --port 6379 --healthcheck tcp

          kustron env up
          
        

Your app now talks to local-ddb:8000, local-s3:80 and kivo:6379 by name. The cache is kivo, our Redis-compatible in-memory store: same protocol, same port, so it drops in where you'd use redis. Prefer the real thing? Swap in redis:7, nothing else changes.


Deploy anything.

Every app lands with a service, so apps reach each other at http://<name>:<port>. Set namespace: per app to isolate any of them.

Local source

Point to a folder. Kustron uses your Dockerfile if it exists, or Railpack to containerize automatically.

source: ./path

Git repository

Provide a git SSH URL. Kustron clones it, builds it, and deploys it. SSH access must already be set up.

source: git@…

Container image

Use any image from Docker Hub or any registry. Perfect for databases and third-party services.

image: postgres:15

Helm chart

Install any Helm chart into your environment. Pass values directly from the yaml file.

helm: {chart: …}

The commands you'll actually use.

env
kustron env init Create a kustron-env.yaml in the current folder, pre-filled with the folder name as the app.
kustron env up Bring up the cluster and deploy all apps from kustron-env.yaml. Idempotent, safe to re-run.
kustron env reload Stop all apps and bring them back up. Run this after changing kustron-env.yaml. The cluster itself is not destroyed.
kustron env watch Watch local source directories and kustron-env.yaml, auto-redeploy on changes.
kustron env stop Stop all apps (scale to 0, uninstall helm charts) without destroying the cluster. Fast to restart with env up.
kustron env show-spec Pretty-print the full kustron-env.yaml schema with annotations.
kustron env status Show the cluster and every app's state (Running, image pull failed, crash loop) in one table.
kustron env down Deprecated. Destroys everything. Use env stop to pause, or env destroy to explicitly tear down.
teardown
kustron env destroy [--yes] Tear it all down: deletes the k3d cluster (and all data in it), the kubeconfig context entry, and the local state file. Confirmation prompt unless --yes is passed.
apps
kustron apps add [flags] Add an app entry to kustron-env.yaml (--name, --source/--image/--helm-chart, --port, --env…). Then run kustron env reload to apply.
kustron apps remove <name> Remove an app entry from kustron-env.yaml. Then run kustron env reload to apply.
kustron app stop <name> Stop a single app without affecting the rest of the environment.
kustron app start <name> Start a single app that was previously stopped.
kustron app logs <name> [-f] [-t N] Stream logs for a single app. -f to follow, -t N for the last N lines.
kustron app exec <name> [command...] Run a command inside a running app container. Defaults to sh if no command given.
kustron app forward <name> <localPort> [remotePort] Forward a local port to an app. Useful for services that are not exposed via NodePort.
container registry
kustron registry login <server> Log in to a container registry (docker/podman) so private images can be pulled and pushed.
kustron registry prune Remove unused images from the local registry to reclaim disk space.
doctor
kustron doctor Check that the runtime dependencies (container runtime, k3d, kubectl, railpack, helm, git) are installed and the container daemon is reachable. Exits non-zero if anything required is missing.

What you need installed.

Kustron tells you exactly which of these are missing and how to get them: run kustron doctor to check, or let the install script set everything up for you.

⚡

Recommended: OrbStack over Docker Desktop. OrbStack starts in ~2 seconds (vs 30+), uses a fraction of the memory, and has native Apple Silicon support. orbstack.dev →

🛠️

Or let the install script do it. It sets up the container runtime, k3d, kubectl, railpack (plus optionally Helm and git) — asking y/n before each step, or pass -y to accept all — then installs kustron from npm.

$ curl -fsSL https://raw.githubusercontent.com/itsmunim/kustron/master/install.sh | bash
required

Node.js 18+

Kustron is a Node CLI installed from npm (Node >= 18). brew install node or nvm.

required

Container runtime

OrbStack (recommended on macOS) · Podman (any platform) · or Docker Desktop. Kustron auto-detects whichever you have.

required

k3d

brew install k3d  ·  k3d.io/installation

required

kubectl

brew install kubectl

optional

Railpack

Only needed when deploying source without a Dockerfile. railpack.io

optional

Helm

Only needed when deploying Helm chart apps. brew install helm

optional

git

Only needed when deploying from a git SSH URL. Usually pre-installed.


Your whole stack, live on one VM.

Not just for local dev. Run it on any cloud VM and your stack, APIs, frontends, databases, is on the real internet. No cluster management.

1

Get a VM

Any Linux instance works: EC2, DigitalOcean Droplet, Hetzner Cloud, Linode. Even a $6/month box is enough for a real multi-service stack.

2

Install prereqs & add your SSH key

Install the container runtime (Docker or podman), k3d, kubectl, and kustron. Add your GitHub (or GitLab) SSH key so kustron can pull private repos directly on the instance.

3

Write your kustron-env.yaml

List your apps with exposed: true for anything that needs to be public. Kustron maps each port to the VM's network interface.

4

Bring it up

One command: cluster, registry, images, deployments, all at once.

5

Open the firewall & share the URL

Allow the exposed ports in your security group (AWS) or firewall rules. That's it, your stack is live at <vm-ip>:<port>.

Your VM: 1.2.3.4
kustron environment
frontend :8080 live
api :3000 live
postgres :5432
redis :6379
↓
1.2.3.4:8080  ·  1.2.3.4:3000
accessible from anywhere
🔒 Only open ports you intend to expose. Internal services like postgres and redis stay internal. Never expose them.

Good questions, quick answers.

Which container runtime should I use, and how do I set it up?

OrbStack (macOS, recommended): brew install --cask orbstack, open it once, done. Kustron detects it automatically.

Podman (any platform): brew install podman (macOS) or your package manager (Linux), then podman machine init --rootful --cpus 4 --memory 4096 and podman machine start. The kustron installer does all of this for you and checks the daemon is responding.

Docker Desktop works too, but it's heavy with k3d. See the next question.

Docker Desktop + k3d hogs my CPU

Docker Desktop runs Linux in a VM, and k3d runs its own cluster inside that VM. Two layers of virtualization means the k3d containers keep chewing CPU even when idle, plus several GB of RAM. OrbStack and Podman don't stack a second VM on top, which is why k3d is much happier on both.

“cannot create network with name 'bridge' because it conflicts with a valid network mode”

Podman reserves bridge as a network mode keyword, so a network can't be named that. Kustron used to try creating one before starting the cluster, which is exactly where this error came from. k3d handles networking itself (it auto-creates a k3d-<cluster> network on podman), and current kustron versions just let it. Update kustron with npm update -g kustron and run kustron env up.

Railpack won't install, and I use a private npm registry

Railpack used to ship on npm, so npm i -g railpack broke for anyone pointed at a private registry. It's not on npm anymore: the installer downloads the prebuilt binary straight from GitHub releases. No npm, no brew, no package manager involved.

Building an app that pulls private npm deps (without a Dockerfile)? Keep your .npmrc auth or NPM_TOKEN env var in the app's build environment so railpack can authenticate.

Port 5000 is already in use

Kustron probes ports with an exclusive bind, so services that are genuinely listening there (macOS AirPlay is a classic on port 5000) are honored and the registry picks the next free port. You can also set a specific port via config.registryPort in kustron-env.yaml.

Once created, the port is stable: kustron reads it back from the running registry container every run, so image pushes can't end up on a stale port. The registry itself is cluster-scoped — kustron-registry for the default cluster, <clusterName>-registry otherwise — so multiple local clusters don't fight over one registry.

Podman machine runs out of memory while k3d runs

A k3d cluster wants around 4GB in the podman VM. On macOS: podman machine init --rootful --cpus 4 --memory 4096 for a new machine, or podman machine set --memory 4096 + restart for an existing one.

Will Kustron change my kubectl context?

No. Kustron never calls kubectl config use-context. Every kubectl and helm command includes --context=k3d-<clusterName> (or --kube-context for helm), so your global kubectl context is never touched. You can safely run kustron env up while working with production clusters in other terminals.