The Pragmatic Homelab Playbook: Self-Hosting, GitOps, and Real-World Automation

The Pragmatic Homelab Playbook: Self-Hosting, GitOps, and Real-World Automation

Hook

A few years back I watched my entire home lab blink offline when my internet connection hiccupped for 15 minutes. No external dashboards, no remote access, no CI jobs running, no automated backups. It wasn’t a disaster, but it was a wake-up call: if you want reliable self-hosting, you need a setup that doesn’t depend entirely on a single extroverted cloud-like illusion—even in a home environment. You want something that’s boringly reliable, locally controllable, and still multi-tenant enough to be useful as you scale. This is that practical playbook.

Start with the one hard rule most home labs ignore: simplicity at the edge beats complexity in the core. You’re not building a Google cluster; you’re building something you can operate while sleep-deprived and wearing headphones. Below is a lean, actionable approach I’ve refined over years of chasing real-world reliability without throwing budget at unicorns.

1) Define the non-negotiables before you buy a motherboard

The first thing I hammer into new homelabbers: list your workloads and map failure modes. Common non-negotiables include:

  • Source of truth and CI for your projects (Git hosting, CI runner).
  • A small but resilient Kubernetes cluster or container platform to run apps.
  • Centralized monitoring, logs, and alerting.
  • Automated backups and a tested restore process.
  • A secure remote access path (VPN or zero-trust gateway) and TLS everywhere.

Everything else is gravy. Once you know which workloads must stay online even if your WAN goes down, you can design around that reality instead of chasing “cloud parity” in a LAN.

2) Pick a pragmatic stack that you can maintain

Hardware

  • Start with a used or enterprise-refurbished server with ECC RAM if possible. Aim for 32GB+ RAM for a two-node cluster, more if you’re running multiple VMs or heavy containers. Don’t skimp on storage speed—NVMe caches, SATA SSDs, and a single large spinning disk for bulk storage give you a good mix.
  • A small UPS to cover outages is cheaper than you think and buys you time to gracefully shut down.

Software and architecture

  • Host OS and virtualization: Proxmox VE is my default due to its simplicity, KVM-based virtualization, built-in backup tooling, and straightforward UI. It also plays well with ZFS and Debian-based desktops/servers.
  • Virtualization approach: Run a few VMs for core services (Git server, CI, Kubernetes control plane) and use containers inside VMs for flighty workloads. For a lighter path, you can start with Docker Compose on a single VM and move to a small Kubernetes cluster later.
  • Cluster choice: A two-node (or three-node) Open Source Kubernetes cluster using k3s (or K3d for testing) is a solid path if you’re installing modest workloads. If you want ultra-low friction, you can do a single node cluster and layer GitOps on top—less complexity, still valuable for learning.

Storage strategy

  • ZFS on the Proxmox host for VMs, with a separate pool for backups and a shared storage pool for container data. ZFS’s snapshots and send/receive features make backups and DR straightforward.
  • Separate data disks for each VM to minimize contention. Use ZFS datasets to isolate app data from system data.

Networking and security

  • Design a simple but segmented network: a management network for Proxmox, a VM network for workloads, and a secure boundaries network for management from your LAN. VLANs and a basic firewall (or a dedicated edge/router VM) can do wonders for containment.
  • VPN or zero-trust access for remote work. WireGuard is fast and reliable; Tailscale makes peer-to-peer access painless if you’re in a multi-site home lab or frequently on the road.
  • TLS everywhere with a reverse proxy. Consider Caddy, Traefik, or Nginx with Let’s Encrypt certificates. If possible, terminate TLS at the edge and re-encrypt internally.

3) GitOps and self-hosted CI: a pragmatic workflow

What you want is not a monolith like GitLab but a lean, maintainable stack that you actually enjoy using on a Sunday afternoon.

Git hosting

  • Gitea is a lightweight, self-hosted Git hosting option with authentication, webhooks, and a clean UI. It’s fast, easy to back up, and you can run it in a VM or container.
  • If you want more enterprise features later, you can migrate to a larger solution, but start small and stable.

CI/CD

  • Drone CI is a simple, container-based runner that plays well with Git-based triggers (GitHub, GitLab, Gitea, etc.). It’s straightforward to configure, runs in a VM or container, and scales with your needs.
  • For more Kubernetes-native CI, consider a lightweight GitOps approach with Flux or ArgoCD (will be covered in the GitOps section).

GitOps for deploys

  • GitOps is the real payoff for home labs. Use Flux (or ArgoCD if you’re entirely Kubernetes) to declaratively manage your Kubernetes manifests from Git. The core idea: the cluster mirrors what’s in Git, not the other way around.
  • Secrets management: avoid storing cleartext credentials in Git. Use Sealed Secrets (by Bitnami) or SOPS with a KMS. Store the encrypted manifests in Git and decrypt at runtime in the cluster.
  • Reconcile frequency: optimize Flux/ArgoCD to run on a cadence that matches your change velocity. For a home lab, a 1–5 minute reconciliation window is plenty.

Examples to start

  • Example Git repo structure for a home-lab application:
  • /infra/k8s/base: common manifests
  • /infra/k8s/environments/dev/prod: environment-specific overrides
  • /infra/flux: Flux manifests and kustomizations
  • /apps/service-a: Kubernetes manifests for a small app
  • /ci: Drone pipelines for building and pushing container images
  • A minimal workflow:
  • Push code to Gitea
  • Drone picks up the push, runs tests, builds a container image, pushes to a private registry (could be a local Harbor or a simple Docker registry)
  • Flux reconciles the environment from Git, updating Kubernetes deployments, and the app goes live

Practical example: a two-node micro-Kubernetes cluster

  • Node A: control plane (Raspberry Pi 4 in a pinch? If you have an x86_64 spare desktop, even better)
  • Node B: worker
  • Use k3s with a simple high-availability approach (Raft-based datastore on a shared disk or external etcd)
  • Install Flux on the cluster and connect to your Gitea repo
  • Setup Drone with a shared registry (local registry on Proxmox or a dedicated VM)
  • Create a small app (e.g., a static site) to verify deployments, webhooks, and rollback flows

4) Monitoring, logging, and alerting: the boring-but-crucial trio

Reliability in a homelab hinges on visibility. If you can’t see what’s happening, you can’t fix it quickly.

Monitoring

  • Prometheus + node_exporter on each node to collect metrics
  • Grafana for dashboards (start with CPU, memory, disk I/O, network, and container metrics)
  • Use a simple SLA-based alert rule: alert on node CPU > 85% for 5 minutes, disk I/O wait > 40%, or memory usage > 90%

Logging

  • Loki + Promtail for logs; it’s lightweight and integrates naturally with Grafana
  • Keep logs short-term locally, export to an object store or a central VM for longer retention (e.g., 7–30 days)

Backups and DR

  • VM backups in Proxmox (snapshots plus periodic backups)
  • Container