No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-27 06:48:17 +02:00
.vibe switch to vibe 2026-07-27 01:42:59 +02:00
applications switch mail login 2026-07-27 01:53:56 +02:00
batch switch mail login 2026-07-27 01:53:56 +02:00
clusters chore(deps): update fluxcd/flux2 from v2.9.2 to v2.9.3 2026-07-23 16:06:36 +00:00
infrastructure chore(deps): update helm release linkerd2-cni from 2026.7.1 to 2026.7.2 2026-07-24 18:31:44 +00:00
templates docs 2026-07-16 11:37:56 +02:00
traefik-pve-forward fixes 2026-07-23 16:28:37 +02:00
.gitignore get rid of unused services 2026-05-10 10:10:17 +02:00
CLAUDE.md cleanup 2026-07-23 17:01:40 +02:00
LICENSE add MIT LICENSE for going public 2026-05-10 19:21:33 +02:00
README.md cleanup 2026-07-23 17:01:40 +02:00
renovate.json fixes 2026-06-02 05:56:01 +02:00
services.md cleanup 2026-07-23 17:01:40 +02:00

flux

FluxCD GitOps tree for my single Kubernetes cluster (talos-prod). Public so it can serve as a working reference.

This repo is what Flux reconciles. Everything inside the cluster (operators, applications, scheduled jobs, ingress for off-cluster services) is defined here as YAML and deployed by pushing to the branch Flux watches. There is no application code, no build step, no test suite.

What runs here

The cluster bootstraps in layers under clusters/talos-prod/. Roughly:

  • Networking and ingress: MetalLB (L2 LB), Traefik (two instances: internal on 10.50.0.20, external), External DNS to deSEC and Technitium, cert-manager with Let's Encrypt + deSEC DNS-01 webhook.
  • Storage: Longhorn for distributed block storage, CSI NFS for shared file storage.
  • Data: CloudNativePG (Postgres operator with Barman S3 backups), Redis.
  • Identity and secrets: Authentik (OIDC/SAML/LDAP), External Secrets Operator backed by OpenBao (off-cluster), kubernetes-reflector for cross-namespace secret mirroring.
  • Observability: the LGTM stack: Loki (logs), Mimir (metrics), Tempo (traces), Alloy (collection), and Grafana (via grafana-operator), with S3 storage on Garage. Plus kube-state-metrics, metrics-server, and the Prometheus operator CRDs.
  • Document processing: Gotenberg (PDF), Apache Tika (extraction/OCR), used by Paperless.
  • Integrations: a scoped ServiceAccount token (pushed to OpenBao) that lets an off-cluster Home Assistant read and control the cluster.
  • Applications: Immich, Paperless-NGX, Collabora Online, Umami, IT-Tools, Vaultwarden, traefik-whoami.
  • Batch: IMAP backup CronJob (hourly), Renovate (every 30 min).
  • External-service ingress: SNI-passthrough IngressRouteTCP routers on the external Traefik that forward off-cluster Forgejo, Jellyfin, and Seerr to the traefik-pve LXC.

The full catalogue with namespaces and one-line descriptions lives in services.md.

This repo vs. the homelab repo

Two repos, clean split:

  • homelab: everything outside and underneath the cluster: Proxmox VMs, Talos config, OpenTofu that builds the cluster end-to-end, Helm chart sources I maintain, Docker images, host-level scripts. Bootstraps Flux against this repo.
  • This repo (flux): everything inside the cluster, reconciled by Flux. Once the homelab bootstrap finishes, day-2 changes happen here.

Helm charts referenced from this repo (traefik-ingress-chart, cnpg-cluster-chart) are sourced from helm-charts/ in the homelab repo and published to a private Scaleway OCI registry. This repo only consumes them via OCIRepository + HelmRelease.

Layout

clusters/talos-prod/      Flux Kustomization roots — the entry point Flux reconciles
infrastructure/           operators and their config overlays, layered 0..4
applications/             self-hosted apps (immich, paperless, etc.)
batch/                    scheduled jobs (imap-backup, renovate)
traefik-pve-forward/      SNI-passthrough ingress to the off-cluster traefik-pve LXC
templates/                legacy raw CNPG manifests, reference only
services.md               service catalogue: every namespace, one line each

Every category uses the same Kustomize shape: <category>/base/<thing>/ for the manifests, <category>/overlays/talos-prod/<thing>/ for the environment overlay. Overlays currently carry no patches and just re-reference their base. Each directory has its own README with the details.

On AI assistance

I use AI as a research and coding tool. The boring stuff (boilerplate YAML, looking up CLI flags, repetitive Terraform, formatting tables, and documentation, this README included) is AI-assisted. I hate writing docs and basically never had any until AI made it cheap enough to bother. Architecture choices, the stack, debugging when things break, anything operational, and every load-bearing decision in here are mine. If something works well, I picked it on purpose. If something is wrong, that's also on me.

I'm calling it out because it's the honest thing to do.

Caveats

  • It's a single-cluster homelab GitOps tree. Hostnames, IPs, S3 bucket names, and OpenBao secret paths are all tuned to my setup. Cloning this won't reconcile against your cluster without significant rework.
  • Real secret material is not here. Every Secret is either an ExternalSecret resolving against OpenBao, or a placeholder template. The *-config.json.example files show the shape but contain no live values.
  • Host TLS, S3 backup destinations, and DNS provider tokens all assume my domain (webmatix.dev) and my Scaleway / deSEC / Technitium accounts. Swap these before reusing.
  • The linkerd/ stack exists on disk but its Flux Kustomizations are commented out. Linkerd is parked pending a Traefik to Gateway API migration.

License

MIT, see LICENSE. Lift whatever's useful, no permission needed.

Contact

matthias@webmatix.dev, or find me on Codeberg at @webmatix.