Deploy an app
kixctl deploys from git repositories you register. A registered repository holds everything kixctl needs to fetch and build an app: its clone URL, branch, build attribute, and an optional webhook secret. Two triggers land a deploy — a webhook or a poll — and both produce the identical build.
The repository must be a Nix flake describing the app as a kixctl.app spec. That spec, and a full first-deploy walkthrough, are in Your first deploy.
Add a repository
Manage repositories under Settings → Repositories.
- Settings → Repositories → Add repository.
- Repository —
owner/repoas the host reports it (for examplekixago/demo-app). This is the name a webhook payload identifies itself by. - Clone URL — the SSH URL (recommended) or a public HTTPS URL.
- Optional: Name (the stable slug for the app's address and its per-revision instances; blank derives it from the repository name), Branch (blank tracks the default branch), Build attribute (blank uses the install default), Webhook secret, and the Poll toggle and interval.
The minimum is a name and a clone URL. A push or the next poll deploys it.
SSH first
The clone URL carries the authentication. An SSH URL — ssh://git@host:port/owner/repo.git — authenticates through the access the host already has, so a private repository needs no key or token stored in kixctl. A public HTTPS URL works with no credentials. The same clone URL is used for both the poll (git ls-remote) and the pinned build (git+<clone_url>?rev=<sha>).
A repository on a non-standard SSH port must include the port in the URL (ssh://git@git.lan.example.com:2222/…).
Webhook or poll
- Webhook is the low-latency path. Set a webhook secret on the repository, then point the host's webhook at the endpoint for its dialect: Forgejo, Gitea, and Codeberg use
POST /api/deploy/forgejo(or/gitea,/codeberg); GitHub usesPOST /api/deploy/github. The repository is resolved by the payload'sfull_nameand verified against its own secret, so one endpoint serves every repository. - Poll is the host-agnostic baseline. Leave the secret blank and kixctl checks the repository on its interval with
git ls-remote, deploying a new commit with no webhook — the right choice for a mirror or a host you can't webhook.
Both triggers deploy only the tracked branch. A push to any other branch is acknowledged and ignored.
Deploy now
Deploy now on a repository row checks it immediately and deploys its latest commit if that commit isn't already running. It runs the same path on the queue, so progress appears on the Updates tab like any other deploy. Use it to force a retry after a failed build — a normal poll holds a commit it already tried, so it won't rebuild a broken commit every minute.
What a deploy does
A deploy builds a NixOS image pinned to the exact commit, imports it over the Incus API, and launches it as an immutable instance named <slug>-<sha7> on kixctl's own network. The first revision of an app is published so it is reachable by name; a later revision lands alongside the running one and surfaces as update ready for you to promote. See Update and cut over.
What kixctl stores
Stored, encrypted at rest under APP_KEY: the optional per-repository webhook secret. Not stored: any SSH key or access token — SSH authenticates through the host's existing access. Removing a repository deletes its registration only; running revisions and routes belong to the cluster and are left in place.