Homelab Infrastructure

Self-hosted services running on a single-node Talos Kubernetes cluster, provisioned via Terraform on Proxmox and managed through Flux CD GitOps.

Architecture

Proxmox (hypervisor)
└── Talos Linux VM (Kubernetes node)
    └── Flux CD (GitOps)
        ├── config          → cluster-wide variables & secrets
        ├── infrastructure  → Traefik, cert-manager, Authelia, MetalLB, NFS, ...
        └── apps            → application workloads

Repository Layout

homelab-v2/
├── terraform/      # Proxmox VM + Talos cluster provisioning
└── kubernetes/     # Flux CD manifests (Kustomize + Helm)
    ├── config/
    ├── flux-system/
    ├── infrastructure/
    │   ├── controllers/    # Traefik, cert-manager, Authelia, MetalLB, ...
    │   └── configs/        # ClusterIssuer, MetalLB config
    ├── app/
    │   ├── archmirror/
    │   ├── blog/
    │   ├── external/       # External service vars (e.g. Home Assistant)
    │   ├── firefly/
    │   ├── gitea/
    │   ├── grocy/
    │   ├── homepage/
    │   ├── immich/
    │   ├── jellyfin/
    │   ├── lubelogger/
    │   ├── media/
    │   ├── paperless/
    │   ├── pihole/
    │   └── podsync/
    └── docs/
        └── k8s-service-spec.md

Services

Service Description
Gitea Self-hosted Git service
Firefly III Personal finance manager
Immich Photo and video management with face recognition
Jellyfin Media streaming with Intel GPU hardware transcoding
Media Stack Sonarr, Radarr, Prowlarr, qBittorrent — automated media acquisition
Paperless-ngx Document management with OCR
Pi-hole DNS sinkhole with ad blocking and encrypted DNS via dnscrypt-proxy
Grocy Pantry and grocery management
LubeLogger Vehicle maintenance tracker
Homepage Dashboard aggregator
Podsync Podcast downloader
Archmirror Local Arch Linux package repository mirror
Blog Personal static blog served via git-sync + nginx (gh-pages branch)

Infrastructure Stack

Component Role
Flux CD GitOps controller — reconciles this repo to the cluster
Traefik Ingress controller with Let's Encrypt TLS
cert-manager TLS certificate provisioning (Cloudflare DNS-01)
Authelia SSO / OIDC provider for protected services
MetalLB Bare-metal load balancer
NFS Provisioner Dynamic PVC provisioning backed by Synology NAS
Intel GPU Plugin Hardware transcoding device plugin (Jellyfin)
SOPS + age Secret encryption at rest

Storage

  • Synology NAS — primary storage backend for all services
    • Dynamic NFS PVCs via nfs-synology-ssd storage class
    • Static NFS PVs for media library and document archives
  • local-path-provisioner — node-local storage for SQLite databases

Backups

Unified strategy using restic + resticprofile:

  • Primary: Synology NAS via rest-server container (${BACKUP_LOCAL_HOST}:8000)
  • Secondary: Backblaze B2 (offsite), synced via resticprofile copy
  • PostgreSQL: pg_dump init container → restic
  • SQLite: online backup API → restic
  • Files/media: NFS mount → restic

Deployment

All changes are deployed by pushing to this repository. Flux CD reconciles on every commit.

# Check reconciliation status
flux get kustomizations

# Force reconciliation
flux reconcile source git flux-system

# Check application status
kubectl get helmreleases -A
kubectl get pods -A

For initial cluster bootstrap, see kubernetes/README.md.

Security

  • All ingress through Traefik with Let's Encrypt TLS
  • Secrets encrypted with SOPS + age (decrypted at runtime by Flux)
  • SSO via Authelia (OIDC) for user-facing services
  • Per-namespace NetworkPolicies with default-deny + explicit Traefik ingress allow

Provisioning

The cluster is provisioned with Terraform (Proxmox + Talos). See terraform/README.md.

S
Description
No description provided
Readme 2.7 MiB
Languages
HCL 100%