Documentation menu

Changelog

Notable features and fixes per klimax release. The authoritative list of every tagged release lives on GitHub; this page highlights the changes worth knowing about.

🧭

klimax is pre-1.0 and versions with the same date were cut together during rapid iteration. Patch releases with no user-visible change (dependency bumps, CI, docs) are folded into the nearest entry below.

Upgrading between releases? After brew upgrade --cask klimax, destroy and re-create the VM so the new version re-provisions it: klimax destroy && klimax up. Provisioning is baked into the binary, so an in-place VM keeps running the old setup until you rebuild it — the host-backed image cache survives, so it's fast. See Reset.

v0.1.62 — 2026-09-11

  • Added: every pull-through mirror now serves the docker CLI, not just Docker Hub. docker pull quay.io/…, gcr.io and Artifact Registry are cached the same way cluster pulls are. See Registry mirrors and the docker CLI.
  • Fixed: the docs claimed Docker could not mirror anything but Docker Hub. It can — per-registry mirrors go in /etc/docker/certs.d/<host>/hosts.toml, which is a different directory from the one the kind nodes use. Testing the wrong one produced a wrong conclusion.
📦

Applied by klimax up, with no Docker restart — the config is read on each pull. Nothing to change in your config file: the mirrors you already have are the ones that get wired up.

v0.1.61 — 2026-09-11

  • Added: Docker Hub pulls from the docker CLI now go through klimax's pull-through cache. Previously only kind clusters used the mirrors, so docker pull and docker compose fetched from the internet every time and counted against Docker Hub's rate limit. See Registry mirrors and the docker CLI.
  • Changed: the progress messages during a long VM start now name the phase they are waiting on, and say explicitly when the guest provisioning scripts are running. A first boot spends about four of its five minutes installing packages, Docker, kind and kubectl, which previously looked like a hang.
📌

This entry originally said the other mirrors could never serve the docker CLI, because the daemon "has no per-registry mirror setting". That was wrong — it does, through hosts.toml, just not through the setting we were looking at. v0.1.62 ships the rest.

v0.1.60 — 2026-09-11

  • Added: klimax works behind a corporate proxy. Your Mac's system proxy is picked up automatically; network.proxy overrides it. The proxy reaches everything that pulls — the Docker daemon, the registry mirrors, and the containerd inside every kind node — and klimax computes no_proxy itself from the bridge CIDR, the cluster subnets and the mirror names, so cluster-internal traffic is never sent to a proxy that cannot route it. See Configuration → Behind a corporate proxy.
  • Added: vm.caCerts.files trusts extra certificate authorities — a TLS-intercepting proxy, or a private registry with a self-signed chain. Installed in the VM, in every registry mirror, and in every kind node, since each keeps its own trust store. See Trusting extra certificate authorities.
🔐

Both are applied by klimax up without recreating the VM, and removing either takes effect the same way. Clusters created before you add a certificate need recreating, because a kind node's trust store is set up when the node is built.

v0.1.59 — 2026-09-10

  • Added: vm.mounts — a list of host directories to share into the VM, so bind mounts from your Mac work. Each entry takes a location (~ expanded), an optional writable (default false) and an optional mountPoint. Every shared directory appears in the VM at the same absolute path, which is what makes docker run -v ~/projects/conf:/etc/app resolve.
  • Added: klimax status now lists the VM's host mounts (and flags a config change waiting to be applied). It reads the instance config, so it works on a stopped VM.
📁

Docker runs inside the VM, so it resolves a bind-mount source there. Before this release a bind for an unshared host path did not fail — the daemon created the missing directory in the guest and the container saw an empty one. If a container ever mysteriously found nothing where your files should be, this was why.

🧭

Changing vm.mounts does not need klimax destroy. klimax up compares the list against the VM and offers to restart it — a restart still stops every kind cluster on the VM, so it asks first, and changes nothing when run non-interactively. See Configuration.

v0.1.58 — 2026-09-10

  • Changed: vm.cpus and vm.memory now default to a share of your Mac rather than to fixed numbers, so one config suits a 16 GiB Air and a 64 GiB Studio. CPUs get three quarters of the cores; memory gets half the RAM. A 10-core, 32 GiB M1 Pro gets 8 CPUs and 16 GiB. Anything you set explicitly still wins.
Mac RAMVM memoryShare
8 GiB4 GiB50%
16 GiB8 GiB50%
24 GiB12 GiB50%
32 GiB16 GiB50%
64 GiB32 GiB50%
🧭

macOS keeps the other half, whatever the machine. Disk sizes stay fixed, since they are sized by what images need rather than by the machine, and both disks are sparse.

v0.1.57 — 2026-09-09

  • Changed: new resource defaults — cpus: 8, memory: "20GiB", disk: "20GiB", imageDisk: "30GiB". The root disk is smaller than before because imageDisk is now on by default: container images live on that separate disk, so the root disk only carries the OS, Docker metadata and volumes. Both are sparse — the sizes are ceilings, not what they consume on your Mac. Existing configs are untouched; defaults apply to values you have not set.
  • Changed: imageDisk defaulting to 30GiB means klimax destroy no longer discards the container image store. Recreating the VM stops re-pulling every image — and a locally built image, which no registry mirror can restore, is no longer lost.
  • Added: klimax up warns when a config asks for more than the Mac has — more CPUs than cores, more memory than RAM, or a disk total beyond free space. It never blocks: the disks grow on demand and macOS swaps rather than refusing, so each warning names the setting to lower and leaves the decision to you.
  • Fixed: klimax up --show-vm-logs now shows the boot logs on its own. It enabled Lima's reporting but klimax silenced the output, so it only worked when paired with --debug — which nothing told you.

v0.1.56 — 2026-09-09

  • Changed: klimax up now reports progress while the VM starts. Between Starting Lima instance and VM is running it used to print nothing at all — on a first boot that gap is minutes of image download, boot and cloud-init, and it reads as a hang. A line every 15 seconds says otherwise. Restarting an already-provisioned VM takes about 14 seconds, so the common case still prints nothing extra.
  • Changed: the note listing config options your file does not set now links the configuration reference and the annotated example. It used to say "see config.example.yaml", a file that only exists in the repository — a Homebrew install has no copy of it.

v0.1.55 — 2026-09-09

  • Added: klimax disk resize-image <size> grows the persistent image-cache disk in place, keeping the images on it. vm.imageDisk sizes the disk mounted over /var/lib/containerd — which is where images actually live, since Docker in the VM uses the containerd snapshotter. That disk fills long before the VM root disk does.
  • Fixed: raising vm.imageDisk in the config used to do nothing to an existing VM, silently. The size applies only when the disk is first created, so the only way to get a bigger one was to delete it — discarding the image cache the disk exists to preserve. klimax up now warns when the live disk and the configured size disagree, and quotes the command that fixes it.
💾

Growing the image disk needs the VM stopped, because Lima locks the backing file while an instance holds it: klimax down && klimax disk resize-image 30GiB && klimax up. The guest partition and filesystem grow on the next start; shrinking is not supported.

v0.1.54 — 2026-09-07

  • Fixed: klimax fleet export wrote the zero value of every optional field, so a one-cluster export opened with an empty defaults: block and lines like strategy: "", registries: null and dependsOn: []. Valid YAML, but an exported manifest is something you then edit, and that noise reads as configuration someone chose rather than left unset. Unset fields are now omitted.
  • Fixed: klimax doctor now notices when the hostagent's binary was replaced underneath it. The previous check compared the running binary's path to the current one, which cannot see an in-place overwrite — both sides read the same string. That is exactly what make dev-install does, and it is what makes macOS amfid kill subsequent klimax commands, so doctor reported everything healthy while the machine was in the broken state the check exists to catch. It now compares the binary's timestamp against the hostagent's start time.
🔎

Upgrading via Homebrew does not hit the amfid problem — it writes a new file and re-points a symlink, so the running hostagent keeps its own copy. You will still see the new warning after an upgrade, and it is worth acting on: the hostagent is running the older klimax until you rebuild the VM.

v0.1.53 — 2026-09-06

  • Security: bumped golang.org/x/crypto to v0.56.0 for GO-2026-6354 and GO-2026-6355, two denial-of-service flaws in x/crypto/ssh that klimax reached through its own guest SSH and hostagent paths. Unlike the stdlib CVEs patched earlier, a newer Go toolchain does not clear these — only a dependency bump does.
  • Added: klimax fleet export — the inverse of fleet create -f. Reads live clusters and writes a Fleet manifest, so an ad-hoc lab can be captured into a reproducible file. Select clusters by name, by -l selector, or from an interactive picker. See Fleet management → Exporting a fleet.
  • Added: -o text|json|yaml on klimax status and klimax doctor. They were the two most automation-relevant commands and the only ones without it, so Klimax UI and AI agents had to scrape prose. Text output is unchanged; each doctor check now carries a stable id so tooling can key off route/iptables/ip-forward instead of matching wording.
  • Added: klimax doctor --fix applies the repairs klimax can perform itself — the macOS host route, the iptables no-NAT exemption, and guest IP forwarding. Creating or starting the VM, installing Rosetta, and clearing a stale hostagent stay advisory: the first is klimax up, and the last kills a live process.
  • Fixed: klimax doctor's hostagent check never actually worked on macOS. It compared the running binary via /proc/<pid>/exe, which does not exist on macOS, so the comparison was unreachable — on the only platform klimax supports, and for a failure mode that is macOS-only. Its fallback used os.FindProcess, which on Unix succeeds whether or not the process exists, so any leftover pidfile was reported as a running hostagent. Both fixed; a stale pidfile is now named as such.
  • Changed: building from source now needs Go 1.26+ (was 1.25.7), because x/crypto v0.56.0 requires it. Installing via Homebrew is unaffected — the released binaries are prebuilt.
  • Changed: CI, security scanning and releases now build with the latest stable Go rather than the exact version pinned in go.mod, so stdlib CVE patches are picked up automatically instead of needing a hand-edited pin each time. Released binaries were previously built against a pinned toolchain with known stdlib CVEs.

v0.1.52 — 2026-08-11

  • Added: vm.imageDisk puts the VM's container image store on its own Lima data disk (mounted over /var/lib/containerd), so kindest/node, registry:2 and locally built images survive klimax destroy — a locally built image is the only kind no registry mirror can restore. Unset by default; "10GiB" is a comfortable size. See Configuration → Persistent image store.
  • Changed: the VM is now based on Ubuntu 26.04 LTS. 25.04 was an interim release that had already reached EOL, so freshly created VMs had stopped receiving security updates.
  • Changed: bumped the bundled kind CLI to v0.32.0 and the default kind.nodeVersion to kindest/node:v1.36.1, the image that CLI is validated against.
  • Changed: cluster creation no longer sleeps 5 s before applying the MetalLB IPAddressPool — it retries until the validating webhook accepts it, with a 60 s deadline so a genuinely broken webhook still fails loudly. Measured on a live VM, the MetalLB phase went from 20.4 s to 14.8 s.

v0.1.51 — 2026-08-09

  • Added: klimax shell is now also a command runnerklimax shell <cmd> [args…] runs it in the VM, passes stdin/stdout/stderr through, and exits with the remote command's code, so it composes in pipelines and if tests. Trailing arguments used to be accepted and silently ignored. Flag parsing stops at the first positional (klimax shell docker ps -a works as typed); -t forces a pseudo-terminal. See CLI reference → Running commands in the VM.
  • Added: klimax copy <src>… <dst> copies files either direction over scp. Mark the VM side with a vm: prefix — klimax copy ./x vm:/tmp/x, klimax copy vm:/tmp/x ./x — with -r for directories. See CLI reference → Copying files.
  • Added: klimax sudoers prints NOPASSWD rules scoped to the two /sbin/route commands klimax up needs, so it stops prompting for a password; --check reports whether they're in effect by reading the sudo policy. See CLI reference → Passwordless host route.
  • Added: klimax autostart install|uninstall|status manages a per-user launchd agent (dev.klimax.autostart) that runs klimax up at login, logging to ~/.klimax/logs/autostart.log. It depends on the sudoers rules above — launchd can't answer a password prompt. See CLI reference → Starting at login.
  • Added: klimax disk resize <size> grows the VM disk without recreating the VM — it rewrites vm.disk and the Lima instance config, and the image and guest filesystem expand on the next klimax down && klimax up. Shrinking is refused. See Configuration.
  • Added: klimax prune (--dry-run, --downloads, -y) reclaims superseded Lima guest agents and registry caches whose mirror is no longer configured. Caches of configured mirrors are never touched — that's still klimax registry clean-cache. See Registry mirrors.
  • Fixed: klimax status and klimax doctor reported the macOS host route as present when it was absent — the probe was a plain route -n get, which the default route answers for any address. It now requires the returned destination to be the CIDR's own base, and status prints the gateway it resolved: 172.30.0.0/16 → present (via 192.168.64.3). See Networking & L3 routing.
  • Security: bumped gRPC to v1.82.1 for GO-2026-6061.

v0.1.50 — 2026-07-11

  • Fixed: klimax doctor always reported the no-NAT iptables rule as missing, even right after a successful klimax up. The probe omitted the -d <vm-net> destination qualifier that the installed rule carries — iptables -C requires an exact spec match — and ran unsudoed as the unprivileged lima SSH user, so the permission error was swallowed into a false "missing". It now reconstructs the rule exactly and runs under sudo, making doctor's no-NAT line trustworthy again. See Networking & L3 routing.

v0.1.48 – v0.1.49 — 2026-07-09

  • Removed: the local push registry (kind-registry:5000) is gone — config schema, container, certs.d host mapping, and the Fleet registries.localRegistry toggle all removed. To get a locally built image into a cluster, build against the VM's Docker (eval "$(klimax docker-env)") and load it with kind load docker-image. See Registry mirrors.
  • Changed: network.disablePortMirroring now defaults to true, so klimax coexists with other Lima VMs out of the box and kubeconfigs use the VM's lima0 IP. Set it to false to force loopback (127.0.0.1) addressing — e.g. for a single VM or when host security software blocks vzNAT IPs. See Networking.
  • Added: two Google Artifact Registry pull-through mirrors to the defaults — registry-us-docker-pkgdev (5040) and registry-us-central1-docker-pkgdev (5050), alongside the existing docker.io, quay.io, and gcr.io mirrors.
  • Security: binaries are built with Go 1.25.12 to patch the crypto/tls ECH CVE.

v0.1.43 – v0.1.47 — 2026-07-06

  • Changed: bumped MetalLB to v0.16.1 (the new default kind.metalLBVersion) and tightened LoadBalancer / metrics-server readiness waits to 180 s.
  • Changed: bumped the bundled Lima runtime to v2.1.4 and version-stamped the cached guest agent so it refreshes when Lima changes.
  • Fixed: klimax now rejects hostname-like registry mirror names (any name with a . or :). Such a name shadows its own upstream on the kind Docker network and silently breaks the pull-through cache — use a safe form like registry-quayio. See Registry mirrors.
  • Security: releases now ship SBOMs, CI runs govulncheck with Dependabot enabled, and binaries are built with Go 1.25.11 to pick up the latest stdlib CVE patches.

v0.1.42 — 2026-07-04

  • Added: a top-level klimax kubeconfig command (alias kc) grouping every kubeconfig op — path, env, merge, use (merge + switch context), and remove. See CLI reference → Kubeconfig.
  • Deprecated: klimax cluster use and cluster merge — still work, but prefer kubeconfig env and kubeconfig merge.
  • Fixed: raised the MetalLB and metrics-server readiness waits to 300 s so slower first-pull machines don't time out.

v0.1.41 — 2026-07-04

  • Changed: the embedded Lima logs are hidden by default — klimax quiets them to error so only its own output (and genuine Lima errors) show. Surface them with --debug (Lima at info) or --lima-log-level trace|debug|info|warn|error|off. See CLI reference → Logging.

v0.1.40 — 2026-07-04

  • Added: fleet adoptionklimax fleet adopt <fleet> <cluster>… pulls running clusters into a fleet by setting their klimax.dev/fleet node label. fleet create / cluster apply -f now warn when the manifest lists clusters that exist but aren't fleet members, and --adopt relabels them in place (they show as adopt in the plan). See Fleet management → Adopting existing clusters.
  • Added: klimax up reviews the config before creating the VM — it lists options your file doesn't set that this klimax version supports (defaults apply), and offers to update a pinned kind.nodeVersion that has drifted from the version matched to the bundled kind CLI.

v0.1.38 – v0.1.39 — 2026-07-03

  • Added: klimax fleet describe <name> shows a fleet's member clusters with their num, ports, nodes, and labels (aliases desc, show).
  • Changed: klimax cluster create no longer takes --num — the cluster num is always auto-assigned to the lowest free slot. Pin one where it matters via a Fleet manifest's num: field.

v0.1.36 – v0.1.37 — 2026-07-03

  • Added: a top-level klimax fleet command that operates on live clusters grouped by the klimax.dev/fleet node label — fleet list, fleet create -f, fleet delete <name>|-f, and fleet label <name>. See Fleet management.
  • Added: kubectl-style label selectors on the cluster commands — klimax cluster list -l <selector> to filter and klimax cluster delete -l <selector> to delete matching clusters.
  • Changed: the bundled Agent Skill now covers Fleet manifests and cluster labels.

v0.1.35 — 2026-07-03

  • Added: klimax cluster label <name> relabels an existing cluster's nodes without recreating it — repeatable -l key=value sets or overwrites a label (--overwrite by default), and -l key- removes one. See Managing clusters → Node labels.

v0.1.32 – v0.1.34 — 2026-07-03 · Fleets

  • Added: declarative fleets of kind clusters. klimax cluster apply -f <manifest> reconciles a Fleet manifest (apiVersion: klimax.dev/v1alpha1) into existence — creating missing clusters in dependsOn order, up to maxParallel at a time, with --dry-run and per-cluster registries, addons, and labels. It's additive: existing clusters are skipped, never mutated. See Fleet management.
  • Added: klimax cluster delete -f <manifest> tears a fleet down in reverse-dependency order (-y to skip the prompt).
  • Added: node labels on every cluster — managed-by=klimax always, klimax.dev/fleet=<name> for fleets, topology.kubernetes.io/region + zone, and your own via the manifest labels map or klimax cluster create -l key=value.
  • Changed: the resource formerly called ClusterSet is now Fleet.

v0.1.30 — 2026-07-03

  • Changed: bumped the default Kubernetes node image to kindest/node:v1.35.0 and MetalLB to v0.15.2.
  • Fixed: registry mirrors now work on containerd 2.x — cluster containerd is configured with certs.d hosts.toml files instead of the old containerdConfigPatches. See Registry mirrors.
  • Added: klimax cluster create now warns when kind.nodeVersion is overridden away from the version the bundled kind CLI is validated against — overriding it is unsupported.
  • Added: klimax doctor surfaces Rosetta status, so you can see at a glance whether Rosetta 2 emulation is available in the VM.
  • Fixed: klimax up no longer re-adds the macOS host route (or prompts for sudo) when the route is already correct — repeat runs are quieter and fully idempotent.

v0.1.29 — 2026-07-02

  • Added: klimax skill install ships a bundled Agent Skill that teaches AI coding tools like Claude Code how to drive klimax. Installs into ~/.claude/skills/klimax/ by default; --print emits it for other tools and klimax skill path reports where it lives.

v0.1.28 — 2026-06-17

  • Fixed: the Docker daemon could fail to start inside the VM on hosts whose macOS username is also a valid Linux username. The guest user is now pinned to lima, so the SocketUser=lima override is always valid.

v0.1.24 – v0.1.27 — 2026-04 to 2026-06

  • Changed: bumped the bundled Lima runtime to the 2.1.x series.
  • Fixed: an sshd provisioning idempotency bug — the ClientAliveInterval check is now anchored so Ubuntu's commented-out default is skipped, avoiding SSH socket-permission errors on repeated klimax up.
  • Documentation: added the vs. other tools comparison (including OrbStack) and reworked the diagrams and logo.

v0.1.23 — 2026-04-02

  • Added: kind.customDnsResolvers is now actually wired into each cluster's CoreDNS. Forward specific domains (e.g. an internal corp.internal zone) to chosen upstream resolvers. See Configuration.

v0.1.22 — 2026-04-02

  • Added: network.disablePortMirroring — run klimax alongside other Lima-based tools (Rancher Desktop, Colima) without fighting over 127.0.0.1 port mirroring. With it set, kubeconfigs address the VM's lima0 IP directly. See Networking.

v0.1.20 — 2026-03-30

  • Added: short-name aliases for the main commands.
  • Fixed: prevented SSH socket exhaustion on the guest.

v0.1.0 – v0.1.19 — 2026-03-27 · initial release

  • Multi-cluster kind management on a single Lima (Apple Virtualization.framework) VM, with pure L3 routing — reach pods and LoadBalancer services by their real IP, no port-forwarding.
  • Pull-through registry mirrors for docker.io, quay.io, and gcr.io, plus a local push registry — with a host-backed cache that survives teardowns.
  • Automatic kubeconfig merge/removal on cluster create/delete, plus a cluster merge subcommand.
  • Docker context and docker-env support.
  • Built-in nginx end-to-end routing smoke test, and an ssh-into-the-VM command.
  • Shell completion.
  • Optional Rosetta support; all state stored under ~/.klimax, with a default config generated on first run.

See also