Introduction
I have been running my homelab for more than half a year now and it seems like a good time to document my self-hosting journey thus far. This post will be the beginning of a multi-part series, covering the homelab at a high level before zooming in to greater details.
Hardware
At the time of writing this post, my homelab includes:
- 2 Raspberry Pi 4 Model B (4GB) with PoE+ HAT
- 1 Raspberry Pi 5 (8GB)
- 1 Synology DS920+ NAS with 2 Seagate Ironwolf 4TB hard drives
- 1 TP-Link TL-SG108PE switch
- 1 Linksys E9450 router
The Pis provide the compute layer while the NAS provide the storage layer for the services I self-host.
Software
Let’s start with the operating system. All the Pis are running Raspberry Pi OS Lite (64-bit) which is a port of (Debian 12 Bookworm) while the NAS is running Synology’s DSM 7.2.
For orchestration, all the Pis come together to form a Kubernetes (K8s) cluster with a single control plane node and two worker nodes. The K8s distribution I have went for was K3s, a lightweight distribution that packs all K8s components into a single binary. Just a few curl commands and a cluster is at your disposal.
In terms of deploying services into the cluster, I have decided to go with ArgoCD as my GitOps tool. I have deployed a grand total of 35 ArgoCD apps thus far, excluding one which serves as an app of apps.
Broadly speaking, the apps/services running in the cluster can be divided into two realistic categories:
User-facing apps with actual utility
- Actual: Personal finance app
- Authentik: Identity provider
- Jellyfin: Media system
- Jellyseerr: Media request management system
- Vaultwarden: Bitwarden compatible server
- Synology Drive: File management system*
- Synology Photos: Photo management system*
* Note: these apps are not running in the cluster (runs directly in the NAS instead) but traffic is proxied through a component in the cluster like all other apps
Components that may or may not be necessary
- Networking components
- cert-manager: TLS certificates automation
- cloudflared: Cloudflare tunnel client (for exposing apps publicly)
- ExternalDNS: DNS configuration automation (for Cloudflare and Pi-hole in my case)
- MetalLB: Load balancer implementation for bare-metal K8s clusters
- NGINX Ingress Controller: Ingress controller for NGINX (from F5)
- Pi-hole: DNS server for LAN
- Tailscale Operator: Manages Tailscale proxies (for exposing apps over VPN)
- Observability components
- Grafana: Monitoring dashboards
- kube-state-metrics: Exports metrics for cluster state
- Metrics Server: Container resource metrics for autoscaling
- Node Exporter: Exports machine metrics
- Prometheus Operator: Manages Prometheus and related monitoring components
- Storage components
- NFS CSI Driver: Supports NFS StorageClass
- Synology CSI Driver: Supports iSCSI and SMB StorageClasses
- Media components
- Others
- ArgoCD: GitOps continuous delivery tool
- MongoDB Community Operator: Manages MongoDB community edition
- Sealed Secrets: Sealing secrets using asymmetric cryptography (so that they are safe to check into a git repo)
- Networking components
Conclusion
This concludes the introductory post to my homelab. In the future, I plan to cover networking, storage, as well as some of the pitfalls I have ran into along the way. Stay tuned for more posts if you are interested in any of the above!