Skip to content

Architecture Overview

High-Level Design

                    ┌──────────────────────────────────────────┐
                    │           GitHub (this repo)             │
                    │         master branch = truth            │
                    └─────────────────┬────────────────────────┘
                                      │ push
  ┌───────────────────────────────────────────────────────────────────┐
  │                          K3s Cluster                              │
  │                                                                   │
  │   ┌──────────┐   ┌──────────┐   ┌───────────────────────────┐   │
  │   │  k3s-m1  │   │  k3s-m2  │   │  k3s-oci-m3 (OCI)         │   │
  │   │  master  │   │  master  │   │  master (Tailscale VPN)    │   │
  │   └──────────┘   └──────────┘   └───────────────────────────┘   │
  │                                                                   │
  │   ┌──────────┐                                                   │
  │   │  hoarder │  (NAS — storage only)                             │
  │   │  Unraid  │                                                   │
  │   └──────────┘                                                   │
  │                                                                   │
  │   ArgoCD watches GitHub → applies changes automatically           │
  └───────────────────────────────────────────────────────────────────┘
          ┌─────────┴──────────┐
          ▼                    ▼
  ┌──────────────┐    ┌────────────────┐
  │  Cloudflare  │    │ Tailscale mesh │
  │  DNS/Tunnels │    │ (server comms) │
  └──────────────┘    └────────────────┘

Repository Layout

homelab/
├── kubernetes/               # All Kubernetes manifests
│   ├── bootstrap/            # One-time cluster bootstrap (Helmfile)
│   │   ├── helmfile.yaml     # Installs GPG secret, repo key, ArgoCD, root app
│   │   └── values/           # Values for bootstrap releases
│   ├── apps/
│   │   ├── addons/argocd-apps/    # Master chart — generates all ArgoCD Application CRDs
│   │   │   ├── application.yaml   # Root ArgoCD Application (applied by bootstrap)
│   │   │   ├── values.yaml        # Sets cluster destination for all apps
│   │   │   └── templates/
│   │   │       ├── <namespace>/   # One .yaml per app, one folder per namespace
│   │   │       └── ...
│   │   └── <namespace>/<app>/     # Per-app Helm values
│   │       ├── values.yaml
│   │       └── values.sops.yaml   # Encrypted secrets
│   └── charts/                    # Ad-hoc Kubernetes resource charts
├── ansible/                  # K3s provisioning and server management
│   ├── playbooks/
│   │   ├── k3s-cluster.yml   # Main playbook — includes bootstrap tag
│   │   └── ...
│   ├── roles/
│   └── inventory/
├── terraform/                # External infrastructure
│   └── cloudflare/           # DNS, tunnels, WAF
├── docs/                     # This documentation
└── .sops.yaml                # SOPS encryption rules

Bootstrap vs GitOps

The cluster lifecycle has two phases:

Bootstrap (once) — run manually on a fresh cluster:

uv run ansible-playbook ansible/playbooks/k3s-cluster.yml         # provision K3s
uv run ansible-playbook ansible/playbooks/k3s-cluster.yml --tags bootstrap  # install ArgoCD
See bootstrap runbook for full details.

GitOps (ongoing) — ArgoCD takes over after bootstrap:

  1. A change is committed and pushed to master
  2. ArgoCD detects drift between the cluster state and the Git state
  3. ArgoCD applies the diff — creating, updating, or pruning resources
  4. selfHeal: true ensures any manual in-cluster changes are reverted back to Git state

The argocd-apps chart is the root of the tree. It is itself an ArgoCD Application (defined in application.yaml) that generates all other Application CRDs from the templates/ directory.

Stack Summary

Layer Technology
Kubernetes distribution K3s
GitOps ArgoCD
Ingress ingress-nginx
TLS cert-manager + Let's Encrypt
Load balancer MetalLB
Persistent storage Longhorn
Secret encryption SOPS + PGP
Provisioning Ansible
External infra Terraform
DNS & tunnels Cloudflare
VPN mesh Tailscale