# 02. Local setup and first run

In this tutorial you will deploy one tiny Kix cluster to kind, port-forward to
it, and make one config edit. The point is to feel the loop:

1. **Edit** the cluster or package.
2. **Check** what Kix can prove before touching the cluster.
3. **Deploy** the checked activation.
4. **Verify** with `kix pf`, `curl`, or `kubectl`.
## Prerequisites

- Read [Orientation: what Kix is and why it exists](/docs/tutorials/01-orientation/).
- Install Nix with flakes enabled.
- Have Docker, Colima, or OrbStack running.
- Have `kind`, `kubectl`, and the `kix` CLI available. The next section shows
  one way to get them.

## Start From The Example Repo

The runnable examples live in the public `kix-examples` repo:

<Command commands={[
  "git clone https://github.com/kix-ops/kix-examples.git",
  "cd kix-examples",
]} />

If you already have the repo, use that checkout instead. The commands below
assume you are at the repo root.

Open the files for the first example:

```text
flake.nix
tutorials/02-hello-world/cluster.nix
tutorials/02-hello-world/README.md
kind-config.yaml
```

You do not need to understand all of them yet. For now:

- `flake.nix` exposes the example clusters by name;
- `tutorials/02-hello-world/cluster.nix` defines the first cluster;
- `kind-config.yaml` creates a local kind cluster named `kix-demo`.

## Enter A Shell With The Tools

If your machine already has `kix`, `kind`, and `kubectl` on `PATH`, you can use
your normal shell. If you need the Kix CLI, install it from the public
`kixpkgs` flake:

<Command commands={["nix profile install github:kix-run/kixpkgs#kix"]} />

Keep Docker, Colima, or OrbStack running separately. kind needs a
Docker-compatible daemon to create the local cluster.

Check that Kix can see the example clusters:

<Command {...listClusters} />

You should see `02-hello-world` in the output. If you are not in the example
repo, point Kix at it explicitly:

<Command commands={["kix --flake /path/to/kix-examples list clusters"]} />

The `--flake` flag tells Kix which flake to evaluate. Without it, Kix uses the
current directory.

:::note[Reference]
See [Global flags](/docs/reference/cli/global-flags/) for the exact shared CLI
flags, including `--flake` and `--context`.
:::

## Create The Local Cluster

Start Docker, then create the kind cluster:

<Command commands={["kind create cluster --config kind-config.yaml"]} cwd="kix-examples/" />

This creates a single-node cluster named `kix-demo` and sets your current
`kubectl` context to `kind-kix-demo`.

Check that Kubernetes is reachable:

<Command {...kubectlClusterInfo} />
<Command {...kubectlGetNodes} />

If you already have this kind cluster, `kind` will say it exists. That is fine;
continue with the deploy step.

## Your First Kix Deployment

Deploy the first Kix example:

<Command expandable {...deployFirst} />

The `-y` flag skips the confirmation prompt. On the first deploy, Kix builds the
cluster, sees there is no previous activation, and applies the resources
wave-by-wave — the order you see comes from the deploy graph.

List the packages installed in this Kix cluster:

<Command {...listPackages} />

You should see an installed `hello-world` instance. The `import` rows are
platform pieces (DNS, storage) Kix pulls in automatically — later tutorials
explain them. You can also ask Kubernetes
directly:

<Command commands={[...kubectlPods.commands, ...kubectlSvc.commands]} />

## Reach The Service

The first example installs an `echo-server` package instance named
`hello-world`. Use `kix pf` to port-forward to its primary workload:

<Command commands={["kix pf 02-hello-world hello-world 8080:80"]} cwd="kix-examples/" />

Leave that command running. In another terminal, call the service:

<Command commands={[{ command: "curl http://localhost:8080/", stdout: "Hello from Kix!" }]} />

Stop the port-forward with `Ctrl-C`.

`kix pf` resolves the package instance to the workload Kix built, then delegates
to `kubectl port-forward`. The package name can also be written as
`namespace/name` when a cluster has duplicate instance names, but this first
cluster only has one.

:::tip[Use it in a task]
This tutorial explains how Kix port forwarding works. For flags and command
syntax, see [Use `kix pf`](/docs/how-to/operate-a-cluster/use-kix-pf/).
:::

## Make One Edit

Open `tutorials/02-hello-world/cluster.nix` and find this instance:

<Snippet {...helloWorldInstance} />

Change the message:

```nix title="kix-examples/tutorials/02-hello-world/cluster.nix"
config = {
  message = "Hello from my laptop!";
};
```

Deploy again:

<Command expandable {...deployAfterEdit} />

Port-forward and curl again:

<Command commands={["kix pf 02-hello-world hello-world 8080:80"]} cwd="kix-examples/" />

In another terminal:

<Command commands={[{ command: "curl http://localhost:8080/", stdout: "Hello from my laptop!" }]} />

The response should show your new message.

That edit is small, but it proves the core loop: Kix evaluated the flake,
rebuilt the manifests, applied the changed workload, and left you with a normal
Kubernetes Service and Pod.

## Before Moving On

You have now used:

- `kix list clusters` to discover cluster names;
- `kix deploy <cluster> -y` to apply one cluster;
- `kix list packages --cluster <cluster>` to inspect installed packages;
- `kix pf <cluster> <package> <local>:<remote>` to reach a workload.

The next tutorial steps back from the running cluster and looks at the repo
shape that made those commands work.