nixlab

A NixOS homelab template that stands up a k3s cluster with WireGuard VPN, Nextcloud, Pi-hole, and automatic TLS - all configured from a single file.

What it is

nixlab is an opinionated NixOS flake for running a multi-node k3s homelab. The entire cluster is configured from one file (vars.nix). Adding a node means copying a hardware config template, filling in an IP and disk, and running colmena apply. Everything else - k3s roles, service deployment, disk layout, impermanence, secrets - is derived automatically.

Every boot wipes / via a btrfs rollback in the initrd. Only /persist survives, so your nodes are always in a known-good state.

What's included

ServicePurposeExposure
MetalLBLoadBalancer IPs from your LANpool from vars.metallbPool
LonghornDistributed block storageinternal
nginx ingressHTTP/S ingress controllervars.nginxIp
Pi-holeLAN DNS + ad blockingvars.piholeIp
ExternalDNS (Pi-hole)Auto-registers local DNS from ingressLAN
ExternalDNS (Cloudflare)Auto-registers public DNSpublic
cert-managerLet's Encrypt TLS via DNS-01-
DDNSKeeps Cloudflare A record current-
WireGuardVPN with per-user Nextcloud SSOvars.wireguardIp
NextcloudSelf-hosted cloud storagenextcloud.<vars.domain>
Signal proxySignal messenger proxysignal.<vars.domain>

Design principles

One config file. vars.nix is the only file you edit. Everything the cluster needs - usernames, IPs, domains, nodes, WireGuard users - lives there. Nix propagates it everywhere.

Nodes are just hardware. Every NixOS config comes from modules/system/node.nix, which reads your node's entry in vars.nodes by hostname. A hosts/<name>/hardware-configuration.nix file is the only per-node artifact.

Immutable by default. Every boot starts from a clean btrfs subvolume. State that needs to survive goes into /persist via the impermanence module. This makes nodes predictable and easy to rebuild.

No hand-rolling YAML. Kubernetes manifests are generated in Nix from nixhelm chart definitions and nix-kube-generators. The master node's activation script applies them in dependency order via a systemd service - no external CD tool required.