A Pragmatic Self-Hosted DevOps Stack for the Homelab
If you’re reading this, you’re likely staring at a cheap NAS box, an old server you repurposed, or a pile of Raspberry Pi LEDs that still somehow works when you yell at it. The hook is simple: you don’t need cloud-based imitation of DevOps drama to learn, test, and ship software. You can build a pragmatic, repeatable pipeline at home that teaches you how modern CI/CD, GitOps, and observability actually fit together—without handing over your dashboards to a third party. The hard part isn’t “what to install” so much as “how to keep it sane over time” and “how to avoid turning your homelab into a fragile Frankenstack.” Below is how I built a practical, resilient, self-hosted DevOps stack in my own lab, what I’d change next time, and how you can do it without blowing your budget or your hairline.
Hook: The moment you stop treating your homelab as a haphazard collection of one-off experiments and start treating it like a real platform, you unlock a superpower: every code change you ship is backed by automation, versioning, and a rollback plan—even when you’re deploying to your own devices.
1) Start with the end in mind: what are you actually trying to ship?
- Self-hosted CI/CD that actually resembles production pipelines.
- Git-driven infrastructure with GitOps for at least the core workloads.
- A repeatable, testable pipeline for each project that you can demonstrate to teammates or future you.
- Observability, backups, and security baked in from day one.
If you don’t know what “production” means in your homelab, you’ll end up with a pile of running containers that you never trust to deploy.
2) Hardware and virtualization: what you actually need
Big caveat: you don’t need a data center to start. A compact, energy-efficient box can host most of what follows, with a plan to scale as your needs grow.
- Hardware baseline (home-lab class):
- CPU: 4–8 cores at minimum; more if you’re running Kubernetes nodes or a heavy CI runner.
- RAM: 16–32 GB for a modest multi-node cluster; 64 GB if you’re serious about multiple clusters or large builds.
- Storage: 2–4 disks for ZFS or a robust filesystem; consider an SSD for the OS and an HDD/SSD pool for data.
- Networking: reliable gigabit LAN; consider a small 2.5G link if you’re moving large artifacts around.
- Virtualization approach:
- Proxmox VE is my personal favorite for homelabs because it’s simple to manage, supports containers (LXC) and VMs, and plays nicely with Terraform/Ansible.
- If you’re power-constrained, a lightweight Kubernetes distro (K3s or MicroK8s) on bare metal or in LXC containers can be enough for a small team.
- Storage strategy:
- ZFS (on Linux) for data integrity, snapshots, and easy backups.
- Separate boot/OS drives from data pools to minimize maintenance churn.
- Keep a “lab budget” and buy once. Don’t chase latest hardware; you’re learning to run systems, not to benchmark GPUs.
3) Core software stack: the architecture you’ll actually maintain
A practical homelab stack is modular, opinionated, and boring in management in the best sense. Here’s a balanced recipe:
- Platform and orchestration:
- Proxmox VE as the base layer, hosting LXC containers and VMs. If you’re Kubernetes-curious, run a lightweight cluster on K3s for production-like workloads.
- Source control:
- Gitea or Forgejo (Foss-friendly, self-hosted Git services) for code hosting, issue tracking, and small teams. It’s cheaper to operate than GitLab at scale and easier to back up.
- CI/CD:
- Drone CI or Jenkins X for a self-hosted, container-native CI system. Drone is lighter weight and YAML-driven; Jenkins is heavier but extremely flexible. Pick one based on your comfort with plugins and resource availability.
- GitOps and deployment:
- Argo CD (or Flux) to implement GitOps for Kubernetes workloads. If you aren’t running Kubernetes yet, treat Argo CD as a future upgrade path rather than the core at launch.
- Registry and artifacts:
- A private Docker/OCI registry (Docker Registry with TLS or Harbor for more features) to store build artifacts and images.
- Secrets and configuration:
- Sealed Secrets (for Kubernetes) plus SOPS for non-Kubernetes secrets to avoid plaintext exposure.
- Infrastructure as code:
- Terraform for provider-agnostic infrastructure, plus Ansible for provisioning and configuration management.
- Observability:
- Prometheus for metrics, Grafana for dashboards, Loki for logs; optionally Tempo for traces. A single pane of glass is priceless for triage.
- Backups:
- Restic or BorgBackup to back up important data to local storage plus remote targets (S3-compatible storage, Backblaze B2, or your own object store).
Edge advice: keep the stack small enough to understand, but big enough to feel realistic. Start with Git hosting, a simple CI runner, a basic Kubernetes cluster (or just Docker Compose for small projects), and a couple of dashboards. Then add components in layers.
4) Networking and access: how to securely expose a home platform
The moment you expose services to the internet, you take on risk. Do it deliberately.
- Access and VPN:
- Use a VPN or mesh like Tailscale to give you secure, authenticated access into the lab from anywhere. It greatly simplifies firewall rules and keeps you from exposing admin interfaces publicly.
- DNS and TLS:
- Run a small DNS server (or leverage Cloudflare’s private DNS) for internal names. Use a dynamic DNS service if your home IP changes, paired with Let's Encrypt via a reverse proxy for TLS.
- Reverse proxy:
- Deploy Nginx or Traefik as an ingress/controller in front of your apps. Traefik has built-in Let's Encrypt support; Nginx Proxy Manager is a friendlier UI for beginners.
- Segmentation:
- At minimum, isolate CI/CD runners, GitOps controllers, and registry from your home media services. If you’re using Proxmox, you can separate networks with VLANs or dedicated bridges.
Important: don’t expose your management interfaces directly to the internet without MFA, IP allowlists, and strong TLS. It’s not worth the risk.
5) A practical deployment plan: step-by-step, with concrete choices
Step 1: Set the foundation
- Install Proxmox VE on a dedicated box or a small headless server.
- Create two pools: one for VMs/containers that host critical services, one for data/backups.
- Enable ZFS for your storage pool, with periodic scrubs and snapshots.
Step 2: Bring in containerization and a minimal cluster
- Install Docker/Podman on a management VM or a small LXC container if you’re not using full Kubernetes.
- If you want Kubernetes, install K3s on two nodes (one for control plane, one for workers) to create a tiny, resilient cluster. Use a simple service mesh or sidecar if you need more reliability.
Step 3: Git hosting and code visibility
- Deploy Gitea or Forgejo in a container; expose it behind your reverse proxy with TLS.
- Create repos for your infra-as-code, application manifests, and sample projects.
Step 4: CI/CD and GitOps
- Set up Drone CI or Jenkins X in a container. Create a pipeline that builds a sample app, runs tests, and pushes a container image to your private registry.
- Install Argo CD (or Flux) on the cluster. Connect Argo CD to a repo that contains your Kubernetes manifests or Helm charts. Create a simple application that deploys a frontend service.
Step 5: Observability and backups
- Deploy Prometheus