Skip to content
Deploy an app

Deploy an app

A deployment is a named handle on a cluster that you ship releases to. Its name is also its Kubernetes namespace (kbn-<name>). What to run is described by kubrain.yaml, which travels with every release.

1 · Create the handle

kubrain deploy create myapp --cluster prod

Idempotent. As created, this is a manual deployment — you ship it from a local checkout (step 2). To have Kubrain build and roll out automatically on every Git push instead, bind a repository — see Git deployments below.

2 · Ship a release

kubrain deploy ship myapp --dir .          # build local source in the cloud, then roll out
kubrain deploy ship myapp --image ghcr.io/me/myapp:1.4.0   # or roll out a prebuilt image

--dir tars your working tree and the cloud builds it (a privileged BuildKit job in your cluster); multi-component apps build each source component independently and apply the whole set as one release. Then poll:

kubrain deploy get myapp                   # until the release is live

Releases are immutable, named r-N, and flow building → live → superseded (or building → failed). The rendered manifests travel with the release, so rollback re-applies exact prior bytes.

A release can be failed while pods are healthy — most often because the rollout’s Ingress was rejected (another namespace already claims the same host+path). Read the reason from deploy get, resolve the clash, and re-ship.

3 · Build once, promote

Test an artifact in staging, then ship that exact image to prod — no rebuild:

kubrain deploy promote --src staging --to prod          # ships staging's current image on prod
kubrain deploy promote --src staging --to prod --release r-7

prod re-renders with its own kubrain.yaml and secrets, but the image bytes are identical to what you tested.

4 · Roll back

kubrain deploy rollback myapp              # to the last good release
kubrain deploy rollback myapp --to r-5     # to a specific one

No rebuild — it re-points and re-applies the stored manifests.

Git deployments (auto-build on push)

Bind a repository once and Kubrain builds every push for you — no external CI to wire up. This is the “watch my repo and ship it” path.

1 · Bind the repo and add the deploy key

Binding Git mints a read-only, per-deployment ed25519 deploy key; its private half never leaves the platform. Add the public half to your repository (on GitHub/GitLab: Settings → Deploy keys, read-only is enough) so Kubrain can clone and pull:

kubrain deploy create myapp --cluster prod \
  --repo git@github.com:me/myapp.git --branch main   # bind (idempotent — safe to re-run)
kubrain deploy deploy-key myapp                       # print the public key to add to the repo

You can bind an existing manual deployment the same way — re-running deploy create with --repo just updates the binding.

2 · Choose when it builds

A trigger decides which refs auto-build:

kubrain deploy set-trigger myapp --spec commit:main          # every push to main
kubrain deploy set-trigger myapp --spec 'commit:release/*'   # any release branch
kubrain deploy set-trigger myapp --spec 'tag:v*'             # version tags
kubrain deploy set-trigger myapp --spec 'schedule:0 3 * * *' # nightly rebuild
kubrain deploy set-trigger myapp --spec manual               # off — ship by hand only

3 · Push

A background poller watches the bound repo, resolves the matching ref to a concrete SHA, and builds only when it differs from the current release — then pins that exact SHA into the release, so a moving branch can never desync the running image. kubrain deploy get myapp shows the current commit for a Git deployment.

Gates (monorepos). Restrict auto-builds to commits that actually matter: only_paths builds only when matching paths changed; only_message only when the commit message matches — so one service in a shared repo doesn’t rebuild on another’s changes.

Manual and Git-watched shipping coexist: you can still run kubrain deploy ship myapp by hand at any time.

Observe & tear down

kubrain deploy logs myapp                  # tail recent pod logs, live (nothing stored)
kubrain deploy list
kubrain deploy delete myapp                # tears down the namespace — confirm first

See also