Flux GitOps Setup with GitHub
Summary
This post documents how I manage my Kubernetes cluster using Flux and a GitHub repository, and why I chose this approach.
The short version: Git is the source of truth. The cluster continuously reconciles itself toward whatever is declared in the repo.
Why I Chose GitOps
Before GitOps, managing Kubernetes often turns into:
- applying YAML manually
- losing track of what changed
- “it worked yesterday” debugging
- differences between environments
GitOps fixes that by enforcing a clean workflow:
- every change is committed
- every change is reviewable
- rollback is just
git revert - the cluster continuously heals drift
This matters even more in a homelab because:
- I rebuild often
- I test a lot
- I don’t want manual steps that I forget later
The end result is a setup that is easier to maintain and easier to rebuild.
Repository Layout
I keep everything in a GitHub repo. The layout is structured so it scales as the cluster grows:
repo/
clusters/
prod/
flux-system/
infrastructure/
apps/
infrastructure/
ingress/
monitoring/
security/
storage/
apps/
websites/
tools/
gameservers/
What this structure gives me
clusters/prod/is the entry point for that cluster- shared definitions live under
infrastructure/andapps/ - I can add more clusters later (e.g.
clusters/stage,clusters/hetzner)
The key point: Flux watches clusters/prod and everything fan-outs from there.
Bootstrap Flux with GitHub
Flux is bootstrapped directly against GitHub.
Typical workflow:
- Create a GitHub repo (private or public)
- Install the Flux CLI locally
- Bootstrap Flux into the cluster so it:
- installs Flux controllers
- creates
flux-systemnamespace - commits the initial manifests into the repo
- configures deploy keys / GitHub auth
From that moment on, the cluster pulls from GitHub automatically.
Why bootstrap matters
It avoids chicken-and-egg problems. Once bootstrapped, the cluster is self-managing.
Core Flux Objects
Flux revolves around a few core CRDs.
GitRepository
Defines where Flux pulls from.
- repo URL
- branch
- sync interval
Kustomization
Defines what gets applied and how.
- target path in the repo
- pruning behavior
- dependency ordering
- health checks
HelmRepository + HelmRelease
For Helm-managed apps:
- HelmRepository points to a chart repo
- HelmRelease declares chart version + values
This is how I deploy things like:
- Traefik
- kube-prometheus-stack / Grafana
- CrowdSec
How Reconciliation Works
Flux runs a control loop:
- fetch Git repository
- render manifests (Kustomize / Helm)
- apply to cluster
- repeat on interval
If someone changes something manually in the cluster:
- Flux detects drift
- it reconciles back to Git
That is exactly what I want: the cluster should match Git.
Secrets Management (SOPS)
GitOps only works cleanly if secrets can live in Git safely.
I use SOPS-encrypted secrets so I can commit them without exposing plaintext.
High level idea:
- secrets are stored as
secret.enc.yaml - Flux decrypts them during reconciliation
- encryption keys are stored securely (not in plain Git)
This gives:
- repeatability
- versioned secrets
- safe backups of configuration
Promotion and Safety
Even with a single cluster, I want safe changes.
My rules:
- never apply random YAML from my laptop
- prefer HelmReleases so upgrades are tracked
- keep values files small and readable
- use health checks so bad deploys fail fast
Rollback is easy:
- revert commit
- Flux reconciles back
Why This Fits My Homelab
GitOps is often sold as “enterprise tooling”, but it helps a homelab even more.
Because a homelab changes constantly:
- new nodes
- new apps
- migrations
- experiments
Flux keeps this under control by turning the cluster into a reproducible state machine.
If I lose a node or rebuild the whole cluster:
- bootstrap Flux
- point it at the repo
- everything returns
That is the goal.
Final Notes
Flux + GitHub is the foundation for everything else I run:
- infrastructure components (ingress, monitoring, security)
- workloads (websites, tools, game servers)
- secrets and config
It gives me consistency, auditability, and the ability to rebuild without fear.
In other words: fewer manual steps, fewer surprises.