Skip to main content

Overview

The kit includes a complete local development environment using:
  • KinD - Kubernetes in Docker for a local multi-node cluster
  • Tilt - Live development environment with hot reloading
  • mirrord - 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)

Quick Start

1

Create the local cluster

mise run //local:create-cluster
This creates a 3-node KinD cluster (1 control-plane, 2 workers) with a local Docker registry.
2

Start the LoadBalancer provider

In a separate terminal (requires sudo):
mise run //local:cloud-provider-kind
This enables LoadBalancer services to get IPs in the 172.20.0.0/16 range.
3

Start Tilt

mise run //local:tilt-up
Open http://localhost:10350 to view the Tilt dashboard.
4

Access your services

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

What Gets Deployed

Tilt deploys a subset of infrastructure and all demo services:

Infrastructure Components

ComponentPurpose
cert-managerTLS certificates (using self-signed ClusterIssuer locally)
cloudnative-pgPostgreSQL operator for in-cluster databases
traefikIngress controller

Demo Services

The kit includes three variants of go-backend, each demonstrating a different Kubernetes templating approach:
ServiceTemplatingDescription
go-backendKustomizeUses overlays for environment-specific configuration
go-backend-helmHelmTraditional Helm chart with values files
go-backend-timoniTimoniCUE-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:
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:
# 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:
# 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:
# 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 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:
{
  "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

1

Ensure the KinD cluster is running

The service must be deployed in the local cluster (via Tilt) before mirrord can intercept its traffic.
2

Run your service with mirrord

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.
3

Debug as usual

Use your IDE’s debugger, add print statements, or modify code. Changes take effect immediately without rebuilding containers.
Most IDEs have mirrord plugins that integrate debugging directly. See the mirrord IDE docs for VS Code, IntelliJ, and others.

Comparison: Local vs Production

AspectLocal (KinD + Tilt)Production (EKS + ArgoCD)
ClusterKinD (Docker)EKS (AWS)
Registrylocalhost:5001ECR
Ingresssslip.ioRoute53 + real domain
TLSSelf-signedLet’s Encrypt
SecretsLocal valuesAWS Secrets Manager
DatabaseCloudNativePGCloudNativePG (or RDS)
DeploymentTilt (live reload)ArgoCD (GitOps)

Next Steps

With local development set up, you’re ready to start building! See the Operations guides for: