> ## Documentation Index
> Fetch the complete documentation index at: https://kubestarterkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Local Development Setup

> Set up KinD, Tilt, and mirrord for local development

## Overview

The kit includes a complete local development environment using:

* **[KinD](https://kind.sigs.k8s.io/)** - Kubernetes in Docker for a local multi-node cluster
* **[Tilt](https://tilt.dev/)** - Live development environment with hot reloading
* **[mirrord](https://mirrord.dev/)** - Remote debugging by intercepting pod traffic

This lets you develop and test Kubernetes deployments locally before pushing to staging.

## Prerequisites

Ensure you have:

* A container runtime (Docker, Podman, or OrbStack)
* mise installed with tools (`mise install` from [Repository Setup](/usage/getting-started/02-repository-setup))

## Quick Start

<Steps>
  <Step title="Create the local cluster">
    ```bash theme={null}
    mise run //local:create-cluster
    ```

    This creates a 3-node KinD cluster (1 control-plane, 2 workers) with a local Docker registry.
  </Step>

  <Step title="Start the LoadBalancer provider">
    In a **separate terminal** (requires sudo):

    ```bash theme={null}
    mise run //local:cloud-provider-kind
    ```

    This enables LoadBalancer services to get IPs in the `172.20.0.0/16` range.
  </Step>

  <Step title="Start Tilt">
    ```bash theme={null}
    mise run //local:tilt-up
    ```

    Open [http://localhost:10350](http://localhost:10350) to view the Tilt dashboard.
  </Step>

  <Step title="Access your services">
    ```bash theme={null}
    mise run //local:ingress-urls
    ```

    This prints the sslip.io URLs for accessing services:

    * `http://go-backend-kustomize.172-20-0-100.sslip.io`
    * `http://go-backend-helm.172-20-0-100.sslip.io`
    * `http://go-backend-timoni.172-20-0-100.sslip.io`
  </Step>
</Steps>

## What Gets Deployed

Tilt deploys a subset of infrastructure and all demo services:

### Infrastructure Components

| Component          | Purpose                                                    |
| ------------------ | ---------------------------------------------------------- |
| **cert-manager**   | TLS certificates (using self-signed ClusterIssuer locally) |
| **cloudnative-pg** | PostgreSQL operator for in-cluster databases               |
| **traefik**        | Ingress controller                                         |

### Demo Services

The kit includes three variants of `go-backend`, each demonstrating a different Kubernetes templating approach:

| Service           | Templating | Description                                          |
| ----------------- | ---------- | ---------------------------------------------------- |
| go-backend        | Kustomize  | Uses overlays for environment-specific configuration |
| go-backend-helm   | Helm       | Traditional Helm chart with values files             |
| go-backend-timoni | Timoni     | CUE-based configuration with type safety             |

All three deploy the same Go application with:

* PostgreSQL database (via CloudNativePG)
* Database migrations (via Atlas, run as Kubernetes Job)
* Ingress for external access

## Cluster Configuration

### KinD Cluster

The cluster is configured in `local/kind/cluster-config.yaml`:

```yaml theme={null}
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
  - role: worker
```

Key features:

* 3 nodes for realistic scheduling
* Local registry on `localhost:5001`
* Stable Docker network (`172.20.0.0/16`) for predictable IPs

### Local Registry

The `create-cluster` task creates a local Docker registry:

```bash theme={null}
# Images pushed to localhost:5001 are available in the cluster
docker build -t localhost:5001/my-app:latest .
docker push localhost:5001/my-app:latest
```

Tilt automatically builds and pushes images to this registry.

## Tilt Configuration

### Tiltfile Structure

```
local/tilt/Tiltfile              # Main entrypoint
├── kubernetes/src/infrastructure/Tiltfile  # Infrastructure components
└── kubernetes/src/services/Tiltfile        # Application services
```

### Infrastructure Tiltfile

Deploys cluster components in order:

```python theme={null}
# 1. cert-manager (no dependencies)
# 2. cloudnative-pg (depends on cert-manager)
# 3. traefik (no dependencies)
```

Each component uses Helm with local values (`values.local.yaml`).

### Services Tiltfile

For each service:

1. Builds the Docker image
2. Waits for CloudNativePG to be ready
3. Creates a PostgreSQL Cluster CR
4. Runs database migrations
5. Deploys the application

### Customizing Tilt Behavior

Edit the values files for local overrides:

```bash theme={null}
# Infrastructure
kubernetes/src/infrastructure/*/values.local.yaml

# Services  
kubernetes/src/services/*/values.local.yaml
```

## Developing Outside the Container with mirrord

While Tilt runs your services inside containers in the KinD cluster, [mirrord](https://mirrord.dev/) lets you run a service directly on your host machine while staying connected to the cluster. This is ideal when you want to iterate on application code without waiting for container rebuilds:

* **Skip container builds:** Just recompile and restart, no Docker builds or image pushes
* **Use your local tools:** Run with your IDE, debugger, profiler, or any host-native tooling
* **Access cluster resources:** Your local process can reach cluster-internal services (databases, APIs)
* **Inherit pod environment:** Environment variables and secrets from the target pod are available locally

### Configuration

The mirrord config is in `services/go-backend/.mirrord/mirrord.json`:

```json theme={null}
{
  "target": { "path": "deployment/go-backend" },
  "feature": {
    "network": { "incoming": "steal", "outgoing": true },
    "fs": "local",
    "env": true
  }
}
```

This configuration:

* **Steals** incoming traffic from the `go-backend` deployment in the KinD cluster
* Enables **outgoing** connections to cluster resources (database, etc.)
* Uses **local** filesystem
* Mirrors pod **environment variables** to your local process

### Using mirrord

<Steps>
  <Step title="Ensure the KinD cluster is running">
    The service must be deployed in the local cluster (via Tilt) before mirrord can intercept its traffic.
  </Step>

  <Step title="Run your service with mirrord">
    ```bash theme={null}
    cd services/go-backend
    mirrord exec -- go run ./cmd/main.go
    ```

    Your local process now receives traffic that would go to the in-cluster pod.
  </Step>

  <Step title="Debug as usual">
    Use your IDE's debugger, add print statements, or modify code. Changes take effect immediately without rebuilding containers.
  </Step>
</Steps>

<Tip>
  Most IDEs have mirrord plugins that integrate debugging directly. See the [mirrord IDE docs](https://mirrord.dev/docs/ide-plugins/) for VS Code, IntelliJ, and others.
</Tip>

## Comparison: Local vs Production

| Aspect     | Local (KinD + Tilt) | Production (EKS + ArgoCD) |
| ---------- | ------------------- | ------------------------- |
| Cluster    | KinD (Docker)       | EKS (AWS)                 |
| Registry   | localhost:5001      | ECR                       |
| Ingress    | sslip.io            | Route53 + real domain     |
| TLS        | Self-signed         | Let's Encrypt             |
| Secrets    | Local values        | AWS Secrets Manager       |
| Database   | CloudNativePG       | CloudNativePG (or RDS)    |
| Deployment | Tilt (live reload)  | ArgoCD (GitOps)           |

## Next Steps

With local development set up, you're ready to start building! See the [Operations](/usage/operations) guides for:

* [Updating 1st Party Applications](/usage/operations/02-updating-1st-party-applications) - Modify and deploy your services
* [Bootstrapping a New Service](/usage/operations/04-bootstrapping-new-service) - Add a new application
* [Database Operations](/usage/operations/07-database-operations) - Manage migrations and databases
