Architecture¶
System Design¶
This homelab runs on Kubernetes (k3s) with GitOps principles using Flux. All infrastructure and applications are defined as code in this repository.
graph TB
subgraph Cluster["Kubernetes Cluster (k3s)"]
Flux["Flux CD<br/>(GitOps)"]
Apps["Applications<br/>(Deployments)"]
Infra["Infrastructure<br/>(Traefik, Cert-Manager, etc.)"]
Data["Storage<br/>(Longhorn PVCs)"]
end
External["External Services"]
DNS["DNS<br/>(Pi-hole)"]
Git["Git Repository<br/>(source of truth)"]
Git -->|watches| Flux
Flux -->|reconciles| Apps
Flux -->|reconciles| Infra
External -.->|ingress| Infra
Apps -->|reads/writes| Data
External -->|DNS| DNS Key Components¶
Core Kubernetes¶
| Component | Purpose |
|---|---|
| k3s | Lightweight Kubernetes distribution |
| Flux CD | GitOps controller; syncs desired state from git |
| Traefik | Ingress controller & reverse proxy |
| Cert-Manager | Automatic TLS certificate provisioning |
Observability Stack¶
| Component | Purpose |
|---|---|
| Prometheus | Metrics collection & time-series database |
| Grafana | Metrics visualization & dashboards |
| Loki | Centralized log aggregation |
| Promtail | Log shipper (Prometheus agent for logs) |
Storage¶
| Component | Purpose |
|---|---|
| Longhorn | Distributed block storage for PVCs |
| Kopia | Backup & disaster recovery |
Security & Networking¶
| Component | Purpose |
|---|---|
| Pi-hole | DNS filtering & ad-blocking |
| Authelia / LLDAP | Authentication & directory services |
| CrowdSec | Threat detection & intrusion prevention |
| Cloudflare Tunnel | Secure external access |
Deployment Patterns¶
Kustomize¶
Apps and infrastructure are split into:
base/— Generic, reusable manifestsproduction/(or other overlays) — Environment-specific patches & customizations
Example structure:
apps/base/mkdocs/
├── kustomization.yaml # Base defines namespace, images, resources
├── deployment.yaml
├── service.yaml
└── ingress.yaml
apps/production/
└── kustomization.yaml # Overlays: patch replicas, add monitoring, etc.
Flux¶
Flux watches the repository and reconciles:
- Infrastructure — Core services (Traefik, Cert-Manager, etc.)
- Applications — User apps (Immich, Bookstack, etc.)
Both sync from git on intervals (default: 1 minute).
Helm Releases¶
Some components use Helm (e.g., Immich):
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: immich
spec:
chart:
spec:
chart: immich
sourceRef:
name: immich-charts
values:
# Helm value overrides
Network Flow¶
- External request → DNS (Pi-hole) → Traefik (ingress)
- Traefik → routes to service IP (ClusterIP/LoadBalancer)
- Service → load balances to pod replicas
- Pod → accesses storage (PVCs backed by Longhorn)
TLS/HTTPS¶
- Cert-Manager watches Ingress objects for TLS cert annotations
- Automatically provisions certs from Let's Encrypt
- Renews before expiry
Data & Persistence¶
- Database pods use Longhorn
PersistentVolumeClaims - Regular backups via Kopia
- StatefulSet for consistent storage (e.g., Pi-hole)
- PVC snapshots available for disaster recovery
High Availability¶
Where applicable:
- Deployments scaled to 2+ replicas for workload distribution
- Horizontal Pod Autoscaler can scale based on metrics
- Pod Disruption Budgets prevent simultaneous pod evictions
- Anti-affinity spreads pods across nodes
Repository as Source of Truth¶
All infrastructure and app config lives in git:
git log --oneline
# Show all past changes to cluster state
This enables:
- ✅ Auditability — full change history
- ✅ Rollback — revert to prior state by reverting a commit
- ✅ Code review — PRs before production changes
- ✅ Reproducibility — redeploy entire system from scratch