A GitOps-managed Kubernetes homelab built with K3S, Flux CD, and a variety of self-hosted applications.
This repository contains the configuration for a complete homelab infrastructure based on Kubernetes. It uses a GitOps approach with Flux CD to manage deployments, ensuring that the cluster state always matches what's defined in this repository.
The homelab includes:
- Media management (Sonarr, Radarr, Jellyfin, qBittorrent, Bazarr, Prowlarr, Recyclarr)
- Home automation (Home Assistant — runs on an external host, cluster only provides a thin passthrough)
- Photo management (Immich)
- Cloud file sharing (Send)
- Cloud storage (Garage S3, hosted as a TrueNAS app)
- TAK server (CloudTAK)
- Git hosting & CI/CD (Forgejo)
- Password management (Vaultwarden)
- AI chat & agents (OpenWebUI, Hermes)
- Authentication/SSO (Pocket ID)
- Monitoring (Gatus)
For AI Agents: See AGENTS.md for comprehensive context including project structure, technology stack, and development workflows.
The homelab runs on a K3S Kubernetes cluster with the following nodes:
- 3 server nodes (node1, node2, node3)
node1.layertwo.dev (172.31.0.10)
node2.layertwo.dev (172.31.0.11)
node3.layertwo.dev (172.31.0.12)
The network is managed by:
-
MetalLB: Provides load balancing with two IP pools:
- Internal pool: 172.31.0.20-172.31.0.29
- External pool: 172.31.0.30-172.31.0.39
-
Traefik: Serves as the ingress controller with two instances:
- Internal Traefik (172.31.0.20): For internal services
- External Traefik (172.31.0.30): For external access with TLS configuration
-
External DNS: Two instances manage DNS automatically —
external-dns-cloudflarepublishes external-class records to Cloudflare, andexternal-dns-unifipublishes internal-class records (layertwo.dev,layertwo.lan) to the UniFi gateway -
Cloudflare DDNS: Custom container that updates Cloudflare DNS records with the current external IP
Storage is provided by:
- Democratic CSI: Connects to a TrueNAS server (sunbeam.layertwo.lan) for NFS storage (
sunbeam-nfs-csi, RWX capable) - HPE CSI: Connects to the same TrueNAS server over iSCSI for block storage (
sunbeam-iscsi-csi, RWO)
Backups are stored in Cloudflare R2 (S3-compatible storage) with dedicated buckets:
layertwo-dev-volsync: For VolSync backups (persistent volume backups)layertwo-dev-cloudnativepg: For CloudNative PostgreSQL backupslayertwo-dev-tofu: For Terraform state files
- K3S: Lightweight Kubernetes distribution
- Flux CD: GitOps controller that ensures the cluster state matches the repository
- SOPS: Secrets management with encryption
- VolSync: Persistent volume backup and restore
- Democratic CSI: CSI driver for TrueNAS NFS storage
- HPE CSI: CSI driver for TrueNAS iSCSI block storage
- System Upgrade Controller: Manages K3S upgrades
- Traefik: Ingress controller with internal and external instances
- MetalLB: Load balancer for Kubernetes services
- External DNS: Automatic DNS management
- Cloudflare DDNS: Dynamic DNS updater
- Democratic CSI: CSI driver for TrueNAS NFS storage
- HPE CSI: CSI driver for TrueNAS iSCSI block storage
- CloudNative PG: PostgreSQL operator
- Cert Manager: Automatic TLS certificate management
- Pocket ID: Lightweight OIDC provider for SSO
- Gatus: Service health checking and uptime monitoring
- Sonarr: TV show management
- Radarr: Movie management
- Bazarr: Subtitle management
- Prowlarr: Indexer management
- qBittorrent: Download client
- Jellyfin: Media server
- Recyclarr: Configuration management for *arr apps
- Home Assistant: Home automation platform
- MQTT: Message broker for IoT devices
- Zigbee2MQTT: Bridge for Zigbee devices
- Z-Wave JS UI: Management for Z-Wave devices
- Immich: Self-hosted photo and video backup solution
- Send: Self-hosted file/secret sharing (Firefox Send fork)
- Garage: S3-compatible object storage, hosted as a TrueNAS app (the in-cluster directory only holds the IngressRoute/cert/Service pointer)
- Website: Static site serving layertwo.dev
- OpenWebUI: Web UI for interacting with LLMs
- Hermes: AI agent gateway
- CloudTAK: Browser-based TAK (Team Awareness Kit) client and media streaming server
- Forgejo: Self-hosted git service with CI/CD via Forgejo Actions runners
- Vaultwarden: Self-hosted password manager (Bitwarden-compatible)
- Pocket ID: Lightweight OIDC provider
A Python script that updates DNS records on Cloudflare dynamically. It retrieves the external IP address of the machine it's running on and updates the specified DNS record accordingly.
Bridges an OpenID Connect (OIDC) identity provider to SAML 2.0 service providers, connecting Pocket ID to AWS IAM Identity Center (which only supports SAML 2.0 for external identity providers).
The bootstrap directory contains utilities for setting up the K3S cluster:
- Install k3sup:
curl -sLS https://get.k3sup.dev | sh
sudo cp k3sup /usr/local/bin/k3sup- Create a k3sup plan using the devices.json file:
k3sup plan \
devices.json \
--user $USER \
--servers 3 \
--server-k3s-extra-args "--disable traefik" \
--background > bootstrap.sh- Execute the bootstrap script to set up the K3S cluster.
After the K3S cluster is running, Flux CD is installed to manage the GitOps workflow. Flux CD synchronizes the cluster state with this repository, ensuring that all applications and configurations are deployed as defined.
- Cloudflare: DNS management with automatic updates via External DNS and Cloudflare DDNS
Detailed documentation for the various components of the homelab can be found in the docs directory:
- Networking: Details about the networking setup
- Storage: Information about the storage setup
- Media Stack: Documentation for the media management applications
- Home Automation: Details about the home automation setup
- Monitoring: Information about the monitoring stack
- Authentication: Documentation for the authentication setup
- Backup Strategy: Details about the backup strategy
This project is licensed under the terms of the LICENSE file included in the repository.