Skip to content

Bootstrap

Full step-by-step guide to bring up the HomeKube cluster from scratch.

Prerequisites

brew install minikube kubectl flux helm kustomize cilium-cli sops

Docker Desktop must be running. Create a GitHub PAT with repo scope at github.com/settings/tokens.

The HomeKube GPG key must be imported for SOPS to work:

gpg --list-secret-keys homekube@local
# If missing, see docs/identity/sops-secrets.md → "Restore the GPG key"


Step 1 — Start Minikube

Cilium requires --network-plugin=cni to disable the default bridge CNI:

minikube start --driver=docker --network-plugin=cni --addons=metrics-server

Tune resources

Default is 2 CPUs / ~6 GB RAM. Increase if you have headroom:

minikube start --driver=docker --network-plugin=cni \
  --cpus=4 --memory=7168 --addons=metrics-server

Previous cluster?

If you get a certificate error from an old install:

minikube delete
minikube start --driver=docker --network-plugin=cni --addons=metrics-server


Step 2 — Install Cilium

Cilium must be installed before Flux. Without a CNI, no pods can start — including Flux controllers.

cilium install
cilium status --wait        # blocks until all components are healthy
cilium hubble enable --ui   # enables the network flow observability UI

Validate end-to-end connectivity (deploys test pods, checks all traffic paths):

cilium connectivity test

Why before Flux?

See ADR-008 for the bootstrapping constraint explanation.


Step 3 — Bootstrap Flux

export GITHUB_TOKEN=<your-pat>

flux bootstrap github \
  --token-auth \
  --owner=MarcSpeckmann \
  --repository=HomeKube \
  --branch=main \
  --path=clusters/local \
  --personal

Flux will:

  1. Install its controllers into flux-system namespace
  2. Commit clusters/local/flux-system/ to the repository
  3. Begin reconciling all Kustomizations from Git

Step 4 — Restore the SOPS GPG Key

The cluster needs the HomeKube GPG private key to decrypt SOPS-encrypted secrets. This must be done before Flux reconciles the identity and observability Kustomizations.

gpg --export-secret-keys --armor CF7169E94481219626AF34290D18AE7E58FB2D45 | \
  kubectl create secret generic sops-gpg \
    -n flux-system \
    --from-file=sops.asc=/dev/stdin

Verify:

kubectl get secret sops-gpg -n flux-system


Step 5 — Push Local Files

After bootstrap, pull Flux's commits then push all scaffold files:

git pull
git add .
git commit -m "chore: add infrastructure, observability, and ADRs"
git push origin main

Note

If files were already pushed before bootstrap, just force a reconciliation:

flux reconcile source git flux-system
flux reconcile ks flux-system --with-source


Step 6 — Watch Reconciliation

flux get ks -A --watch

Expected reconciliation order:

flux-system                ✅  (immediately)
infrastructure-controllers ✅  (~2 min — downloads cert-manager + ingress-nginx charts)
infrastructure-configs     ✅  (after controllers — creates ClusterIssuer)
observability              ✅  (~3 min — downloads kube-prometheus-stack)
network-policies           ✅  (after controllers — applies NetworkPolicies)
identity                   ✅  (~2 min — starts Keycloak, imports realm)

Total: ~7 minutes on first run (chart downloads included).


Step 7 — Start minikube tunnel

Run in a dedicated terminal and keep it open. This is required for ingress to work on macOS.

sudo minikube tunnel

Expected output:

✅  Tunnel successfully started
🔗  Starting tunnel for service ingress-nginx-controller.


Step 8 — Update /etc/hosts

sudo sh -c 'echo "127.0.0.1  grafana.local keycloak.local" >> /etc/hosts'

Use 127.0.0.1, not minikube ip

On macOS with the Docker driver, $(minikube ip) is not reachable from the host. Always use 127.0.0.1 and keep minikube tunnel running.


Step 9 — Access Services

Grafana (login via Keycloak SSO — admin / admin):

http://grafana.local

Keycloak admin console:

http://keycloak.local/admin

Hubble UI (Cilium network flows):

cilium hubble ui

Kubernetes Dashboard:

minikube dashboard


After minikube delete

When you minikube delete and start fresh, repeat from Step 1. Pay special attention to:

  • Step 4: The sops-gpg secret is deleted with the cluster — must be re-created before Flux reconciles
  • Step 7: minikube tunnel must be started again