https://github.com/anokfireball/homelab-as-code
IaC for going from empty disks to running HA homelab cluster managed using GitOps within 2(-ish) clicks
https://github.com/anokfireball/homelab-as-code
ansible cloud-init devops flux gitops helm homelab k8s-at-home kubernetes netboot pxe selfhosted
Last synced: 6 months ago
JSON representation
IaC for going from empty disks to running HA homelab cluster managed using GitOps within 2(-ish) clicks
- Host: GitHub
- URL: https://github.com/anokfireball/homelab-as-code
- Owner: anokfireball
- License: apache-2.0
- Created: 2024-06-29T09:24:54.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-07-20T18:53:22.000Z (6 months ago)
- Last Synced: 2025-07-20T20:35:48.940Z (6 months ago)
- Topics: ansible, cloud-init, devops, flux, gitops, helm, homelab, k8s-at-home, kubernetes, netboot, pxe, selfhosted
- Language: Jinja
- Homepage:
- Size: 2.28 MB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

![Service Uptime]()
Bootstrap and GitOps sources to get my baremetal homelab set up consistently.
# 🏡 Homelab-as-Code (HaC™)
This repository was born out of the need to better manage an ever-growing homelab environment.
After starting with a simple single-node Docker Compose setup, the increasing number of services began to make maintenance and updates more challenging.
As the complexity grew, it became clear that a more structured, Infrastructure-as-Code approach was needed to:
- keep configurations versioned and thus better documented
- make deployments more consistently repeatable and reliable
- simplify the process of adding new services without losing track of the overall state
- enable easier backup and disaster recovery that is centrally managed
- provide better scalability and resilience beyond a single node
I decided to take this opportunity to properly learn Kubernetes hands-on, embracing the complexity and "feeling the pain" that comes with it rather than _just_ having the theoretical knowledge.
This repo serves as both documentation of my setup as well as a real-world learning experience in managing infrastructure that I rely upon as code.
PS: This setup is mature enough to be girlfriend-approved. 😉
## 🔰 Overview
At the highest possible level, this repo and HaC workflow consists of three parts:
- [cloud-init](cloud-init) contains the stage 1 bootstrapping for the cluster nodes.
This includes only the very basic OS-level configuration required for the other stages of this workflow.
The contained shell script creates all files required to install the OS via [network boot](https://ubuntu.com/server/docs/how-to-netboot-the-server-installer-on-amd64) and without user interaction.
_Triggering_ the network-boot installation is out-of-scope for the moment.
After completion of the cloud-init [autoinstall](https://canonical-subiquity.readthedocs-hosted.com/en/latest/intro-to-autoinstall.html), all nodes reboot and are ready to accept SSH connections.
- [ansible/cluster](ansible/cluster) contains the stage 2 system configuration for the cluster nodes.
This includes a range of tasks including power management, networking setup, and most importantly bootstrapping the kubernetes cluster using [kubeadm](https://kubernetes.io/docs/reference/setup-tools/kubeadm/).
The included Ansible playbook performs the required tasks on the nodes via SSH and a dedicated Ansible user created in the previous step.
After completion of this stage, the Kubernetes cluster is set up with [HA](https://kube-vip.io/) control planes, joined worker nodes, dual-stack [CNI](https://www.tigera.io/tigera-products/calico/), almost working [OIDC authn](https://dexidp.io/), and last but not least a bootstrapped [GitOps](https://fluxcd.io/) setup that is ready to start reconciling.
- [flux](flux) contains the final stage 3 GitOps cluster configuration.
This includes everything running _inside_ kubernetes in the cluster and ranges from basic system infrastructure like [load balancer](https://metallb.io/), [ingress](https://kubernetes.github.io/ingress-nginx/), and [CSI](https://longhorn.io/) to more user-style applications such as [password manager](https://bitwarden.com/) and [file management](https://nextcloud.com/) apps.
The included Flux kustomizations are automatically installed and/or reconciled on the cluster without* user interaction.
This process is staggered since there is an inherent dependency between some of the components.
After completion of this stage, the cluster is fully set up and ready for use.
In addition to the core homelab IaC, there is one more loosely related stage:
- [ansible/gateway](ansible/gateway) contains system configuration for a remotely hosted ingress gateway used to expose select services publicly.
This includes setup of [GitOps](https://docs.ansible.com/ansible/latest/cli/ansible-pull.html) outside of Kubernetes, [mesh networking](https://tailscale.com/) outside of Kubernetes, and a [reverse proxy](https://caddyserver.com/) with ACME support.
The included Ansible playbook performs the required tasks on a manually provisioned gateway via SSH and a dedicated Ansible user also created manually.
After completion of this stage, the public gateway is set up and ready to reverse proxy connections to the cluster.
## 📐 Tech Stack
| Component | Purpose | Notes |
| -------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------- |
| [Ubuntu Server 24.04](https://ubuntu.com/server) | Base Operating System | |
| [cloud-init](https://cloud-init.io/) | Headless OS Installation | see [cloud-init/README.md](cloud-init/README.md) |
| [Ansible](https://ansible.com/) | OS Configuration | |
| [kubeadm](https://kubernetes.io/docs/reference/setup-tools/kubeadm/) | k8s _Distribution_ / Install Mechanism | stacked HA controlplanes |
| [containerd](https://containerd.io/) | OCI Runtime | |
| [Calico](https://www.tigera.io/tigera-products/calico/) | CNI | dual-stack nodes and services |
| [kube-vip](https://kube-vip.io/) | Virtual IP for controlplane Nodes | used in L2/ARP mode |
| [Flux2](https://fluxcd.io) | GitOps Automation inside the Cluster | |
| [SOPS](https://getsops.io/) | Secrets Management | [age](https://age-encryption.org/) rather than PGP, but not any more user-friendly |
## 📱 Applications
### 🤖 System-Level
Name
Purpose
Notes
metallb
Cloud-Native Service LoadBalancer
used in L2/ARP mode, so only VIP rather than true LB
external-dns
DNS Management Automation
split-horizon realized using opnsense webhook
cert-manager
Automated Certificate Management
Let's Encrypt via ACME DNS
ingress-nginx
Ingress Controller
Kyverno
Policy Engine
Spegel
Cluster-Internal P2P Container Image Distribution
basically mandates the use of digests or good pinning
longhorn
Cloud-Native Distributed Block Storage CSI
democratic-csi
CSI for Common External Storage Systems
using the freenas-nfs implementation
Renovate Bot
Dependency Update Automation
used for multiple repos, not just this one
k8up
Cloud-Native Backup/Restore
CloudNativePG
Cloud-Native PostgreSQL Operator
Grafana
Monitoring and Observability
Prometheus
Metrics Aggregation and Storage
Loki
Log Aggregation and Storage
Scrutiny
Drive Health Monitoring
via SMART
microsocks
Lightweight SOCKS5 Server
poor man's monitoring gateway, alternatives: OpenSSH, Istio
descheduler
Pod Eviction for Node Balancing
reloader
Hot-Reload for ALL Workloads
Dex
OIDC Provider
used for API server authentication
Tailscale
Overlay Mesh VPN Operator
metrics-server
Metrics API
Goldilocks
Resource Recommendation Engine
Vertical Pod Autoscaler
Workload Resource Scaler
used exclusively for Goldilocks recommendations
### 👨💻 User-Level
Name
Purpose
Notes
Pi-hole
Filtering DNS Proxy
Nextcloud
File Storage and Management
Vaultwarden
API-compatible Password Manager
Immich
Photo/Video Storage and Management
Paperless-ngx
Document Management System
Firefly III
Personal Finance Manager
including importer and pico
KitchenOwl
Recipe and Grocery Manager
Homepage
Application Dashboard
Fresh-RSS
RSS Aggregator
RSS-Bridge
Unofficial RSS Feeds of ANY Source
any as long as you know some PHP
Soundcloud Scraper
Parser + Webhook for my Soundcloud Feed
Stirling PDF
Swiss-Army Knife for PDFs
UniFi Network Application
AP Administration and Management
OPNsense Prefix Updater
Update Network Configs with Latest Non-Static IPv6
n8n
Workflow Automation
freemium/open core
Jellyfin
Media Streaming and Management
Gluetun
VPN Gateway
qBittorrent
Torrent Client
SABnzbd
Usenet Client
Prowlarr
Torrent & Usenet Indexer Engine
Radarr
Movie Management
Sonarr
TV Show Management
Lidarr
Music Management
FlareSolverr
Cloudflare Protection Bypass
## ☁️ Cloud Dependencies
While the ultimate goal is to have as self-sufficient of a setup as possible, some external services are still required for proper operation.
| Service | Purpose | Notes |
| ----------------------------------------- | ---------------------------------------- | --------------------------------------------------- |
| [GitHub](https://github.com/) | Git Repository Hosting, GitOps Source | |
| [INWX](https://www.inwx.de/) | Domain Registrar | |
| [Cloudflare](https://www.cloudflare.com/) | Public DNS Auth Hosting | |
| [Let's Encrypt](https://letsencrypt.org/) | SSL Certificates | |
| [netcup](https://www.netcup.de/) | Public Reverse-Proxy for Select Services | |
| [BackBlaze](https://www.backblaze.com/) | Cloud Storage for Backups | the "3" in 3-2-1 for the really important data |
| [TailScale](https://tailscale.com/) | Overlay Mesh VPN | used for split-horizon and a direct route back home |
| VPN Provider | VPN Gateway | unassociated external IP for all the Linux ISOs |