ArgoCD & GitOps
App-of-apps, sync waves, server-side diff, health checks, performance tuning. Read more →
Pick a question. Follow the steps. Each one teaches you a piece of the architecture.
Create a folder
mkdir -p my-apps/development/my-appAdd a kustomization.yaml — this is what ArgoCD reads
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources: - deployment.yaml - service.yamlAdd your deployment
apiVersion: apps/v1kind: Deploymentmetadata: name: my-appspec: replicas: 1 strategy: type: Recreate # Always use Recreate with RWO PVCs selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: nginx:latest ports: - containerPort: 80 name: http # Named ports required for Gateway APIPush to Git — ArgoCD discovers it within 60 seconds
git add my-apps/development/my-app/git commit -m "add my-app"git pushUse for: App data that needs backup, replication, and snapshots.
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: my-app-data labels: backup: "hourly" # Triggers entire backup pipeline!spec: accessModes: [ReadWriteOnce] resources: requests: storage: 10Gi storageClassName: longhornUse for: AI models, media libraries — large files shared across pods.
apiVersion: v1kind: PersistentVolumemetadata: name: my-models-pvspec: capacity: storage: 500Gi accessModes: [ReadWriteMany] persistentVolumeReclaimPolicy: Retain storageClassName: "" mountOptions: - nfsvers=4.1 - nconnect=16 # 16 TCP connections per mount - rsize=1048576 # 1MB read ops - wsize=1048576 # 1MB write ops - noatime csi: driver: nfs.csi.k8s.io volumeHandle: my-models-pv volumeAttributes: server: "192.168.10.133" share: "/mnt/BigTank/k8s/my-models"Use for: Caches, temp data — node-local SSD, no replication.
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: my-cachespec: accessModes: [ReadWriteOnce] resources: requests: storage: 50Gi storageClassName: local-pathThis cluster uses Gateway API (not Ingress).
Ensure your Service has named ports — Gateway API matches on port name, not number
apiVersion: v1kind: Servicemetadata: name: my-appspec: selector: app: my-app ports: - port: 80 targetPort: 80 name: http # Required! Without this, routing silently failsCreate an HTTPRoute
apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: my-appspec: parentRefs: - name: internal # or "external" for internet access namespace: gateway hostnames: - "my-app.vanillax.me" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: my-app port: 80Push to Git — that’s it, traffic flows automatically
Never commit secrets to Git. Store them in 1Password, reference via ExternalSecret:
Add the secret to 1Password — create an item in the homelab-prod vault
Create an ExternalSecret resource
apiVersion: external-secrets.io/v1kind: ExternalSecretmetadata: name: my-app-secretsspec: refreshInterval: 1h secretStoreRef: kind: ClusterSecretStore name: 1password target: name: my-app-secrets creationPolicy: Owner data: - secretKey: API_KEY remoteRef: key: my-app # Item name in 1Password property: api_key # Field name in that itemReference in your Deployment — as env var or volume mount
env:- name: API_KEY valueFrom: secretKeyRef: name: my-app-secrets key: API_KEYEverything starts from one script:
./scripts/bootstrap-argocd.shThis installs ArgoCD and applies the root application. ArgoCD then discovers everything in Git and starts deploying wave by wave.
Sync waves ensure correct ordering — each waits for the previous to be fully healthy:
| Wave | What deploys | Why this order? |
|---|---|---|
| 0 | Cilium, ArgoCD, 1Password, External Secrets | Pods need networking and secrets |
| 1 | Longhorn, Snapshots, VolSync | Apps need persistent storage |
| 2 | PVC Plumber | Must run before Kyverno calls its API |
| 3 | Kyverno | Webhooks must register before app PVCs |
| 4 | cert-manager, GPU operators, Gateway, DBs | Core services |
| 5 | OTEL, Prometheus, Loki, Grafana | Observability |
| 6 | All user apps | Auto-discovered from Git |
When an app’s PVC is recreated during DR:
backup: hourly label)dataSourceRef into PVCArgoCD & GitOps
App-of-apps, sync waves, server-side diff, health checks, performance tuning. Read more →
Backup & Restore
One label, automatic Kopia backups via Kyverno + VolSync + PVC Plumber. Read more →
CNPG Disaster Recovery
Postgres recovery, ArgoCD race handling, serverName bumps. Read more →
Network Security
Cilium policies, LAN isolation, threat modeling, lateral movement prevention. Read more →
Network Topology
10G infrastructure, NFS tuning, IP layout. Read more →
VPA Optimization
Vertical Pod Autoscaler + Kyverno — right-size everything. Read more →