# Your first deploy

This page assumes kixctl is installed and an Incus cluster is registered. With that in place, a deploy is two things: a repository kixctl can build, and the push-to-live loop.

## A deployable repository

kixctl deploys a repository that is a Nix flake describing your application as a single declarative spec. Using the kixctl builder, the whole of what kixctl needs is a `kixctl.app` block — the language, the source, the entrypoint, and the port the app listens on:

```nix
kixctl.app = {
  language = "node";        # Node or Python today
  src = ./demo-app;
  entrypoint = "kixctl-demo-app";
  pname = "kixctl-demo-app";
  port = 8080;              # the port your app listens on
};
```

From that one spec the builder assembles the image, the systemd service, the firewall opening, and the credential env-bridge that hands your app its injected configuration at startup. You describe what the application *is*, not how to package it.

## Register the repository

In kixctl, register the repository with its clone URL, its branch, and the build attribute — the name of the flake output to build. Fetching is SSH-first by design: a private repository reached over `ssh://` authenticates through the access the host already has, so kixctl stores no deploy key or token at rest. kixctl learns of new commits one of two ways — a webhook you point at it, with the secret held encrypted, or polling on an interval you choose.

## The push-to-live loop

Push a commit. kixctl builds a NixOS image pinned to that exact commit, launches it as an immutable instance named `<app>-<sha7>` on its own internal network, and — for the first revision of an application — publishes it so it is reachable by name.

Push again, and the new revision lands *alongside* the running one without taking traffic, surfacing as "update ready." You promote it with a cutover when you are ready, not automatically. If a promotion goes wrong, revert to the previous revision — it is still there, intact.

That whole lifecycle is the subject of [Immutable deploys](../concepts/immutable-deploys.md) and [Rollback and the state boundary](../concepts/rollback-and-state.md). This is where you first watch it happen.
