A Pragmatic Self-Hosted DevOps Stack for the Homelab

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