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/ and apps/
  • 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:

  1. Create a GitHub repo (private or public)
  2. Install the Flux CLI locally
  3. Bootstrap Flux into the cluster so it:
    • installs Flux controllers
    • creates flux-system namespace
    • 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.