Deploy to infrastructure nobody else can reach.
Kaja is the control plane for Kubernetes clusters you already run: in your cloud account, in your own building, or inside a customer's network with every inbound port closed. Push-to-deploy, a preview environment for every pull request, managed databases, domains and HTTPS, logs and metrics, across the whole fleet from one console.
Free to use today, on any number of clusters. No cloud account to connect and no card to enter.
Live · deployment #7
acme/web:sha-a1b2c3d
2 hours ago
Deployment history
4 of 143Cache the session lookup
DeployLive#7a1b2c3dPushed by @octocatacme/web:sha-a1b2c3d
about 2 hours ago
1m 24s
Configuration changed
Config#6Manual
5 hours ago
12s
Rolled back
Rollback#59f4e1a8Redeployedacme/web:sha-9f4e1a8
2 days ago
48s
Add the health endpoint
Deploy#43c7d052Pushed by @octocatacme/web:sha-3c7d052
4 days ago
1m 02s
One command, and you never leave the terminal. The CLI signs you in, connects your cluster and installs the agent, so there is no token to copy from anywhere.
curl -sfL https://kaja.dev/cli.sh | sh -s -- --initInstalls the CLI, signs you in and connects your first cluster. macOS and Linux.
01What stays yours
- Outbound only
- The agent opens one connection to Kaja and accepts none. No port is opened, no firewall rule is added, and your API server is never exposed.
- Your credentials stay put
- No kubeconfig leaves your cluster, and we never receive credentials for your Kubernetes API. Kaja holds a hashed agent token and nothing else. If the agent stops dialling out, our access ends with it.
- Standard Kubernetes underneath
- Everything the console creates is an ordinary Kubernetes object. Uninstall the agent and your apps keep serving exactly as they were.
- Your compute, unmetered
- Apps, builds, logs and metrics all run on hardware you already pay for, so there is nothing there for us to charge you by the unit.
02The product, running
One minute, cluster to serving.
A cluster with no public address, connected, deployed from a Git repository, given a managed database, published on a real domain over HTTPS, and rolled back. Every screen is the console's own interface, and no YAML is written at any point.
03Who it's for
You already own the hardware. That was the hard part.
Kaja is worth the most in the four situations a hosted platform handles worst.
You repatriated, and the developer experience stayed behind
The servers cost a fraction of the cloud bill and the deploys got measurably worse. Kaja puts push-to-deploy, rollbacks, HTTPS, logs and metrics back on top of hardware you own, without standing up a platform team to keep them there.
Your clusters sit where nothing can dial in
A rack in the building, a machine behind CGNAT, an edge site on a mobile connection. Here that is a supported configuration rather than an exception, because the connection is opened from your side.
You ship your software into your customers' infrastructure
Every customer runs their own cluster, on their own network, under their own rules. Kaja gives you one console across all of them, with no VPN into each site and no customer kubeconfig that you are now responsible for holding.
You have more clusters than you have dashboards
Development on a laptop, staging on a box, production in two regions. One organization, one set of roles and one audit log across every cluster, and a project you can duplicate onto a different one.
04How it works
Three steps, and the last one is git push.
01
Connect a cluster
One command against a cluster you already run, or against a bare machine to have Kaja install k3s first. The agent registers itself and dials out. You open no ports and hand over no credentials.
02
Point Kaja at your code
Connect a GitHub repository and Kaja builds it on your own cluster, from your Dockerfile or a buildpack. Already publishing images? Deploy those instead, from any registry.
03
Push
Every push builds and rolls out as a numbered revision. You get a URL immediately, HTTPS on your own domain when you add one, and a one-click rollback to any revision that came before.
05Preview environments
Every pull request gets the whole stack.
Turn previews on for a project and each pull request against it gets a copy of that project, on its own URL, with its own database. It is torn down when the pull request is.
Reviewing a change by reading it is guesswork once the change touches a migration, a queue or a third-party callback. This is the same environment a hosted platform gives you for a frontend, except it holds the backend too, and it runs on your own hardware rather than being billed per environment per month.
- The whole project, not one container
- Apps, managed services, secrets, routes and scheduled tasks are all copied. A branch that adds a queue and a migration gets the queue and runs the migration.
- Its own database, with its own credentials
- Every preview gets a fresh instance by default, so a half-finished migration cannot reach real data. Per service you can instead restore the base project's most recent backup into it, point the preview at the base project's own instance, or leave that service out. Whichever you chose is named in the pull request comment rather than left to be discovered.
- The URL arrives where the review is
- Kaja posts one comment on the pull request and edits that same comment as commits land: every app with its URL and the state of its build, the commit being served, and the services the preview was given. When a build fails, the comment says the URL is still serving the older image instead of leaving a reviewer to assume it is not.
- It cleans up without being asked
- Deleted when the pull request merges or closes, removed after a week with no pushes, and capped so a busy repository cannot fill a cluster. Pull requests from forks are refused unless you deliberately allow them.
Before you switch them on, the console adds up what one preview will reserve: the apps and services it copies, and the CPU and memory they ask for. Kaja does not autoscale your hardware, so that number is stated in advance rather than discovered a week later.
06How it reaches your clusters
The connection only goes one way.
You install an agent that makes outbound connections and accepts none. No open port, no exposed API server, no kubeconfig shared with us. A cluster behind NAT with every inbound port closed still serves real traffic on a real domain over HTTPS.
This is the part worth checking against anything else you are evaluating. Platforms that deploy into infrastructure you own generally require two things of it: that it can provision a public load-balancer address, and that their control plane can reach its Kubernetes API. Kaja requires neither, which is why a cluster in a rack behind CGNAT is a supported setup here rather than an unsupported one.
Underneath the console, everything Kaja creates is a standard Kubernetes object in your cluster. If our control plane is unreachable, your apps keep serving and you keep kubectl. You lose the console, not production.
Someone opens your app in a browser
Kaja
Runs on our infrastructure
Console & API
Holds the state you asked for
Gateway
Routes on the server name, never decrypts
Your infrastructure
Cloud, on-prem, or a box under your desk
Agent
Dials out, pulls work, applies it
Your apps
Standard Kubernetes objects
No inbound ports. Your cluster opens the connection and keeps it open, and requests travel back down that same connection. A machine behind NAT with every inbound port closed still serves real traffic on a real domain.
Or run the control plane yourself.
The console, the API and the gateway can all run inside your own network, with no dependency on us at runtime. Metadata, tokens and audit records stay inside your perimeter, and no traffic is counted because none of it reaches us. This is the answer to a data residency, sovereignty or air-gap requirement.
The Helm charts exist and the docs cover the deployment. Tell us what you need and we will help you stand it up.
07What Kaja does today
Everything below is built and usable now.
This is an inventory, not a roadmap. If something is missing from it, it is missing from the product.
Deploying
- Connect a GitHub repository once and every push builds and rolls out. There is no pipeline to write and no runner to keep alive.
- Or deploy an image you already publish, from any registry, public or private.
- Builds run on your own cluster, from your Dockerfile or a buildpack. They are never billed by the minute, because they never run on our hardware.
- Every deploy is a numbered revision, and rolling back to any of them is one click.
- Builds and rollouts share one timeline, showing what shipped, the commit it came from, and whether a push or a person started it.
- A deploy tells you what it changed, in the words the console uses: the image, the variables, the resources, the domains. Not two YAML documents to compare by eye.
- Open a pull request and it gets the whole project on its own URL, torn down when the pull request closes.
Scheduled and one-off work
- Run a container on a cron schedule for the work nobody should have to remember: nightly reports, cleanups, retries, expiries.
- A task inherits an app's image, variables and secrets, so most tasks are that app with a different command.
- Run any task by hand and watch its logs while it runs. Every run is kept in the task's history with its outcome, what triggered it and the reason it failed, so the one that failed at 3am is still there in the morning.
- Give an app a pre-deploy command and it runs with the incoming image before that version serves anything. Migrations belong here: a non-zero exit stops the rollout and leaves the previous version up.
- Per task: a timeout, a retry count, and what to do when the last run is still going. Overlapping runs are refused by default.
Traffic and domains
- Every app is reachable on a generated URL the moment it deploys.
- Attach your own domain and certificates are issued and renewed for you, wildcards included.
- Domain ownership is verified when you attach it and re-checked afterwards, rather than trusted once and forgotten.
- Clusters with no public address publish through a gateway we operate. It terminates no TLS, so your traffic stays encrypted from your visitor to your cluster.
Databases and services
- PostgreSQL managed by CloudNativePG, with failover, pgvector, and extensions you switch on from the database's own settings.
- MySQL managed by the Percona operator, fronted by a connection proxy.
- MongoDB managed by the Percona operator, run as a replica set with a volume of its own.
- Redis running Valkey, as a cache or as a durable instance with its own volume.
- ClickHouse for analytics, Qdrant for embeddings and vector search, and OpenSearch for full-text search.
- S3-compatible object storage on your own cluster, so files and backups have somewhere to go without a cloud account.
- RabbitMQ speaking AMQP 0-9-1, so Celery, Bull, Sidekiq and Spring AMQP connect to it unchanged.
- NATS with JetStream for background jobs and events, and a mail catcher that holds everything a staging app tries to send rather than delivering it.
- Point a managed database at any S3-compatible bucket and it takes scheduled backups, keeps the history, and requires a final snapshot before it will let you delete the database.
- Apps bound to a database get their connection details injected, including a DATABASE_URL.
Starting from something
- One-click stacks. Metabase, Umami, WordPress and OpenClaw each arrive wired to the database, secrets and disk they need.
- Save any project as a template, then spawn new environments from it.
- Duplicate a running project, onto the same cluster or onto a different one.
Operating it
- Stream logs and watch CPU and memory per app, stored on your own hardware and not on ours.
- Open a terminal inside a running app or database from the console, so you can run one psql without kubectl access to the cluster.
- Images built from distroless or scratch have no shell to attach to, so Kaja offers to run a debug container beside them instead.
- Pause a project to scale it to zero without losing any configuration.
- Attach a persistent disk to an app, so a stateful workload keeps its data across restarts and redeploys.
- Configs and secrets per project, synced to the right cluster and mounted into your apps.
- The agent updates itself from the console, so a fleet of clusters does not drift apart.
From your terminal
- The kaja CLI deploys, tails logs, manages secrets and domains, and opens a shell.
- It signs in through your browser, so there is no API token to create, store or rotate.
- kaja dash is a live dashboard of a project inside your terminal.
- kaja port-forward points psql, DBeaver or any other local tool at a database inside a cluster with no public address, over the connection the agent already holds. It listens on loopback only, and there is no flag to change that.
- kaja mcp gives an AI agent the same view over MCP. Read-only unless you opt into a write tier, no tier deletes anything, and no tool ever returns a secret's value.
Teams and governance
- Admin, editor and viewer roles, with per-resource permissions.
- An audit log of every change.
- Terminal access is a permission of its own. Restrict it to admins, or switch it off for the whole organization and cut every live session.
- Any number of clusters in one organization, managed by one team from one console.
08What it costs
Your compute is never metered.
Your apps, builds, logs and metrics run on hardware you already pay for. That costs us nothing, so there is no per-container, per-build-minute or per-gigabyte-of-logs line item, and there will not be one. Kaja is free to use today on any number of clusters, and exactly one resource is counted.
- Free today
- Every feature, on every cluster, for everyone in your organization. There is no billing in the product, so there is nothing to buy and nothing to cancel.
- The one thing counted
- Traffic our gateway carries for a cluster with no public address of its own. That path runs on bandwidth we rent, which is the only part of your traffic we pay for. The allowance is 10 GiB a month.
- Never counted
- Anything your own load balancer serves. It goes from your visitors straight to your servers and never reaches us, so there is nothing for us to measure.
When paid plans arrive, they will price the control plane and the gateway. Your compute will still not be metered, because it is not ours to meter.
09The boundaries
What Kaja does not do.
Two of these are deliberate product decisions and two are facts about a young vendor. All four are better read here than discovered during an evaluation.
We do not sell you servers
There is no Kaja-hosted compute option and no plan for one. You bring the infrastructure. That is the reason your compute is not metered and your data does not move.
No compliance certification
There is no SOC 2 report and no third-party audit. The security page states what the agent can do inside your cluster, what leaves your infrastructure and how secrets are stored, so the controls can be evaluated directly rather than through a badge.
No uptime commitment
There is no SLA on the console. The mitigation is structural: your workloads are ordinary Kubernetes objects, so if our control plane is unreachable your apps keep serving and you keep kubectl.
Network isolation ships switched off
Projects can be isolated from each other at the network level. Parts of that are verified on real clusters and parts are not, so it stays opt-in per cluster until all of it is.
Connect a cluster and deploy something.
If you already have a cluster running, this takes a few minutes. Still weighing it up? The questions people ask first are answered in one place.
Rather talk to an engineer first?
Tell us what you are running and we will walk you through connecting the first cluster. Clusters in awkward places are the case we are most interested in hearing about.