Cat Factory
Home
Get Started
GitHub
Home
Get Started
GitHub
  • Start

    • Introduction
    • Core Concepts
    • Quick Start
    • Tutorial: Your First Task to a Merged Pull Request
  • Guides

    • Recipes

      • Cookbook
    • Plan the work

      • Design Your Board
      • Clarify Requirements
      • Author a Document
      • Plan an Initiative
    • Run pipelines

      • Choose and Edit a Pipeline
      • Run a Pipeline
      • Schedule Recurring Work
      • Review and Merge Pull Requests
      • Control Spend with Budgets
    • Connect

      • Connect a Repository
      • Connect Issue & Document Sources
      • Feed Design Context to Agents
      • Preview and Test a Frontend
    • Models & prompts

      • Connect a Model Provider
      • Apply Standards with Prompt Fragments
      • Run a Claude Skill as a Step
      • Compare Prompts and Models in the Sandbox
    • Collaborate

      • Invite and Manage Your Team
      • Share Services Across Workspaces
      • Register Foundational Services
  • Deploy

    • Run Locally
    • Deploy to Node.js
    • Deploy to Cloudflare
    • Deploy on Kubernetes
    • Lay Out a Kubernetes Cluster
    • Set Up a Local Kubernetes Cluster on Windows
    • Register the GitHub App
    • Set Up Enterprise SSO
    • Set Up Your Deployment Repository
    • Configuration
  • Operate

    • Observability
    • Set Up Notifications
    • Run Jobs on Your Own Runners
    • Provision Ephemeral Environments
    • Debug a Run from Outside the Browser
    • Troubleshooting
    • Upgrades & Data Retention
  • Extend

    • Add a Custom Agent Kind
    • Add a Custom Gate or Judge
    • Add a Custom Provider
    • Extend the App with Frontend Modules
    • Integration Manifests
    • Give Agents External Tools (MCP)
    • Package a Reusable Operation
    • Register an Initiative Preset
    • Public API
    • Official SDKs
    • MCP Server
    • Cloudflare OS Gatekeeper
  • Reference

    • Architecture
    • Agent Isolation Model
    • Security Model & Hardening
    • Packages & Repository Layout
    • GitHub and GitLab Support Matrix
    • Environment Variables
    • API Endpoint Reference
    • Glossary

Set Up a Local Kubernetes Cluster on Windows

For a developer running Cat Factory on a Windows machine who wants the Kubernetes backends locally: agent containers as pods, ephemeral test environments in real namespaces, or both. It installs the four CLIs without administrator rights, brings up a throwaway cluster, and hands off to the connect form.

You are probably here because cat-factory k3s sent you. That command installs k3s directly on Linux and cannot on Windows, so it points at this page instead and picks the cluster up on its next run.

Deploy on Kubernetes is the page for connecting a cluster you already have, and Lay Out a Kubernetes Cluster is for a cluster that matters. This one is a local cluster on a laptop.

Why k3d rather than k3s

k3s is Linux-only: there is no native Windows build. k3d runs a real k3s cluster inside Docker, which on Windows means Docker Desktop. You get the same distribution and the same behaviour, one container layer down, and no WSL2 k3s install to maintain.

Pointing at a k3s running inside WSL2 works too and is supported, but k3d on Docker Desktop is the shorter path and the one this page installs.

Before you start

Docker Desktop, running. The cluster's nodes are Docker containers. Check with docker version.

Nothing else is required. The steps below download release binaries into a per-user directory, so there is no package manager to install, no UAC prompt, and nothing written to Program Files. Chocolatey and winget also carry all four tools if you prefer them; choco install needs elevation.

Install the CLIs

Four tools: kubectl drives the cluster, k3d creates it, and kustomize and helm render the manifests an ephemeral environment deploys. Run this in PowerShell.

$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'                       # faster Invoke-WebRequest
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$bin = Join-Path $env:USERPROFILE 'bin'
New-Item -ItemType Directory -Force -Path $bin | Out-Null
$tmp = Join-Path $env:TEMP 'k8s-dl'
New-Item -ItemType Directory -Force -Path $tmp | Out-Null

# kubectl (single exe)
Invoke-WebRequest 'https://dl.k8s.io/release/v1.36.3/bin/windows/amd64/kubectl.exe' -OutFile "$bin\kubectl.exe"

# k3d (single exe, renamed)
Invoke-WebRequest 'https://github.com/k3d-io/k3d/releases/download/v5.7.5/k3d-windows-amd64.exe' -OutFile "$bin\k3d.exe"

# kustomize (the Windows asset is a .zip)
Invoke-WebRequest 'https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v5.8.1/kustomize_v5.8.1_windows_amd64.zip' -OutFile "$tmp\kustomize.zip"
Expand-Archive "$tmp\kustomize.zip" -DestinationPath "$tmp\kustomize" -Force
Move-Item "$tmp\kustomize\kustomize.exe" "$bin\kustomize.exe" -Force

# helm (the .zip contains windows-amd64\helm.exe)
Invoke-WebRequest 'https://get.helm.sh/helm-v4.2.3-windows-amd64.zip' -OutFile "$tmp\helm.zip"
Expand-Archive "$tmp\helm.zip" -DestinationPath "$tmp\helm" -Force
Move-Item "$tmp\helm\windows-amd64\helm.exe" "$bin\helm.exe" -Force

# Add the bin dir to the USER PATH (persistent, no admin). Skips if already present.
$userPath = [Environment]::GetEnvironmentVariable('Path','User')
if (($userPath -split ';') -notcontains $bin) {
  [Environment]::SetEnvironmentVariable('Path', "$userPath;$bin", 'User')
}

On arm64 Windows, swap amd64 for arm64 in the URLs. All four publish arm64 builds, and the helm and kustomize archives put their binary under windows-arm64 instead.

The versions above are the ones Cat Factory's own deploy image ships, so a local run behaves like a deployed one. Any recent release drives a cluster fine; pin these if you want to reproduce what the product does when it renders manifests for you.

Open a new terminal so the PATH change takes effect, then verify:

kubectl version --client   # Client Version: v1.36.3 ; Kustomize Version: v5.8.1 (bundled)
kustomize version          # v5.8.1
helm version --short       # v4.2.3+g...
k3d version                # k3d version v5.7.5

Docker Desktop ships its own kubectl

Docker Desktop installs a kubectl of its own under C:\Program Files\Docker\Docker\resources\bin, which sits on the machine PATH. Windows searches the machine PATH before the user PATH, so a bare kubectl in a fresh shell may resolve to Docker's client rather than the one you just installed.

Both drive a k3d cluster (a slightly older client is compatible), so this is usually harmless. To make yours win:

  • call it explicitly: & "$env:USERPROFILE\bin\kubectl.exe" ..., or
  • prepend the directory for the session: $env:Path = "$env:USERPROFILE\bin;$env:Path", or
  • with admin rights, move %USERPROFILE%\bin ahead of the Docker entry on the machine PATH.

helm, kustomize and k3d have no such conflict: Docker Desktop ships none of them.

Bring up the cluster

# A single-server cluster. Disabling traefik frees port 80 for test workloads;
# drop that flag if you want the built-in ingress and load balancer.
k3d cluster create cf-local --servers 1 --api-port 127.0.0.1:6443 `
  --k3s-arg "--disable=traefik@server:*" --wait --timeout 180s

kubectl get nodes -o wide        # the k3d-cf-local-server-0 node should be Ready

k3d cluster create writes and merges your kubeconfig and switches the current context, so kubectl and helm talk to the new cluster immediately. The first create pulls the rancher/k3s and k3d helper images (a few hundred MB) once; later ones are fast.

Tear it down with k3d cluster delete cf-local. Nothing outside Docker is left behind.

Point Cat Factory at it

Re-run the guided command, which now finds the cluster:

cat-factory k3s

It probes the host, offers to reuse the cluster you just created (or to create another), applies a least-privilege ServiceAccount and RBAC rather than cluster-admin, mints a token, and opens the Infrastructure form pre-filled. The token is printed to the terminal rather than put in the URL, so you paste it, then use Test and Save. The full walkthrough, including the deploy runner a test environment also needs, is Local k3s guided setup.

To fill the form yourself instead, the connection is your new cluster: API server https://127.0.0.1:6443, the ServiceAccount token, and Skip TLS verify for a throwaway cluster whose apiserver certificate is self-signed. Both the Agent containers and Test environments tabs accept it; see Deploy on Kubernetes for what each field does.


Next: connect the cluster on Deploy on Kubernetes, or set up the rest of a local install with Run Cat Factory Locally.

Edit this page on GitHub
Last Updated: 8/9/26, 1:12 PM
Prev
Lay Out a Kubernetes Cluster
Next
Register the GitHub App