GitOps-driven Kubernetes home lab managed with FluxCD
This repository contains the declarative configuration for my personal Kubernetes cluster — a "home-lab" environment where my workloads run through GitOps principles. Every change to the cluster goes through this repo preventing config drift.
The cluster is continuously reconciled by FluxCD, which watches this repository and applies changes automatically. Secrets are encrypted at rest using Sealed Secrets, so it is safe to store them in a public Git repository.
Kubernetes-Flux/
├── bootstrap/ # Flux bootstrap & cluster entry point
├── kappes-space/ # Personal Website
├── longhorn-system/ # Distributed block storage
├── podinfo/ # Podinfo – health check / canary app
├── reflector/ # Secret & ConfigMap replication across namespaces
├── reverse-proxy/ # Reverse proxy for on-prem Workloads
├── sealed-secrets/ # Bitnami Sealed Secrets controller
├── traefik/ # Traefik ingress controller
└── vaultwarden/ # Self-hosted Bitwarden-compatible password manager
| Component | Purpose |
|---|---|
| FluxCD | GitOps operator — keeps the cluster in sync with this repo |
| Traefik | Ingress controller & reverse proxy |
| Longhorn | Cloud-native distributed block storage |
| Sealed Secrets | Encrypted Kubernetes secrets safe for Git |
| Reflector | Mirrors secrets/configmaps across namespaces |
| Vaultwarden | Self-hosted, Bitwarden-compatible password manager |
| Podinfo | Lightweight demo / health-check microservice |
Before bootstrapping Flux, set up the Sealed Secrets controller key so existing sealed secrets can be decrypted:
# Create the sealed-secrets namespace
kubectl create namespace sealed-secrets
# Import your existing keypair
export NAMESPACE="sealed-secrets"
export PRIVATEKEY="mytls.key"
export PUBLICKEY="mytls.crt"
export SECRETNAME="sealed-secrets-key"
kubectl -n "$NAMESPACE" create secret tls "$SECRETNAME" \
--cert="$PUBLICKEY" \
--key="$PRIVATEKEY"
kubectl -n "$NAMESPACE" label secret "$SECRETNAME" \
sealedsecrets.bitnami.com/sealed-secrets-key=activeflux bootstrap github \
--owner=leonkappes \
--repository=Kubernetes-Flux \
--personal \
--path bootstrapFlux connects to this repository and will begin reconciling all resources automatically.
All secrets in this repository are encrypted with Sealed Secrets. The kubeseal CLI is used to encrypt plain Kubernetes secrets into SealedSecret objects before committing:
kubeseal --format yaml < secret.yaml > sealed-secret.yamlOnly the cluster, holding the corresponding private key, can decrypt them.
git push → Flux detects change → applies manifests → cluster converges
- Make changes to YAML manifests in this repository
- Commit and push to
main - Flux reconciles the cluster within its configured sync interval
- Done — no manual intervention required