From 3f82bba25fbe0ed4df36b90e21a9eb1f40f1e27c Mon Sep 17 00:00:00 2001 From: ahmza Date: Wed, 28 Oct 2026 13:02:14 +0000 Subject: [PATCH] Adapt GitOps bootstrap for private single-node Hetzner cluster --- apps/demo.yaml | 2 +- apps/demo/service.yaml | 20 ++++---------------- apps/longhorn.yaml | 2 +- apps/metallb.yaml | 2 +- argocd/app-of-apps/app-of-apps.yaml | 11 +++++++---- docs/04-app-of-apps.md | 13 +++++++++++++ 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/apps/demo.yaml b/apps/demo.yaml index e1e6ac5..34a2f86 100644 --- a/apps/demo.yaml +++ b/apps/demo.yaml @@ -28,7 +28,7 @@ spec: project: default source: - repoURL: https://github.com/YOUR_GITHUB_USERNAME/k8s-starter-pack.git + repoURL: https://tea.ahmza.com/ahmza.com/vps-k8s.git targetRevision: main path: apps/demo diff --git a/apps/demo/service.yaml b/apps/demo/service.yaml index aa5be09..e1f2739 100644 --- a/apps/demo/service.yaml +++ b/apps/demo/service.yaml @@ -3,28 +3,16 @@ # time. This Service selects any Pod labelled app: demo (see # deployment.yaml) and forwards traffic to it. # -# type: LoadBalancer asks the cluster for a real, dedicated IP address that -# anything on your network can reach directly. On a cloud provider that -# would provision an actual cloud load balancer; on bare metal there's -# nothing to provision it, which is exactly the gap MetalLB -# (apps/metallb.yaml) fills — it watches for LoadBalancer Services and -# hands them an address from the pool configured in -# apps/metallb/templates/ipaddresspool.yaml. Until that pool exists, this -# Service's address will show as ; see docs/05-metallb.md. +# ClusterIP keeps this demo internal: this Hetzner deployment does not use +# MetalLB or a cloud load balancer. Reach it with kubectl port-forward over +# the private Kubernetes API rather than opening public application ports. apiVersion: v1 kind: Service metadata: name: demo namespace: demo - annotations: - # Requests this specific address from MetalLB's pool, so it stays - # predictable across rebuilds instead of getting whatever's next free. - # Must fall inside the range in - # apps/metallb/templates/ipaddresspool.yaml, or MetalLB will never - # satisfy the request. - metallb.universe.tf/loadBalancerIPs: "192.168.1.241" # EDIT ME spec: - type: LoadBalancer + type: ClusterIP selector: app: demo ports: diff --git a/apps/longhorn.yaml b/apps/longhorn.yaml index 70af09c..021742b 100644 --- a/apps/longhorn.yaml +++ b/apps/longhorn.yaml @@ -20,7 +20,7 @@ spec: project: default source: - repoURL: https://github.com/YOUR_GITHUB_USERNAME/k8s-starter-pack.git + repoURL: https://tea.ahmza.com/ahmza.com/vps-k8s.git targetRevision: main path: apps/longhorn diff --git a/apps/metallb.yaml b/apps/metallb.yaml index 0311e99..141220e 100644 --- a/apps/metallb.yaml +++ b/apps/metallb.yaml @@ -25,7 +25,7 @@ spec: project: default source: - repoURL: https://github.com/YOUR_GITHUB_USERNAME/k8s-starter-pack.git + repoURL: https://tea.ahmza.com/ahmza.com/vps-k8s.git targetRevision: main path: apps/metallb diff --git a/argocd/app-of-apps/app-of-apps.yaml b/argocd/app-of-apps/app-of-apps.yaml index 605798a..cb538ad 100644 --- a/argocd/app-of-apps/app-of-apps.yaml +++ b/argocd/app-of-apps/app-of-apps.yaml @@ -4,9 +4,8 @@ # gets applied automatically, because this Application's job is to watch # that folder. # -# Before applying this file, edit spec.source.repoURL below to point at YOUR -# fork of this repo (Argo CD needs to clone it, so it must be a real URL it -# can reach — not this template's URL). +# This deployment uses the public repository at tea.ahmza.com. Every child +# Application needs its own matching repoURL; they do not inherit this one. # # >> Ask Claude: "why does the app-of-apps live in argocd/app-of-apps # instead of inside apps/ with everything else?" before moving on — the @@ -20,7 +19,7 @@ spec: project: default source: - repoURL: https://github.com/YOUR_GITHUB_USERNAME/k8s-starter-pack.git + repoURL: https://tea.ahmza.com/ahmza.com/vps-k8s.git targetRevision: main path: apps directory: @@ -34,6 +33,10 @@ spec: # subfolders" — so the app-of-apps only ever sees the Application # manifests, never the workloads themselves. recurse: false + # This single Hetzner node has neither a LAN MetalLB pool nor the + # dedicated disks/extensions expected by Longhorn. Explicitly opt in + # to demo only; extend this filter when adding another Application. + include: demo.yaml destination: server: https://kubernetes.default.svc diff --git a/docs/04-app-of-apps.md b/docs/04-app-of-apps.md index 301c408..358019d 100644 --- a/docs/04-app-of-apps.md +++ b/docs/04-app-of-apps.md @@ -1,5 +1,18 @@ # 04 — The app-of-apps pattern +> **Current Hetzner deployment:** Application sources point to the public +> `https://tea.ahmza.com/ahmza.com/vps-k8s.git` repository on `main`. +> The app-of-apps explicitly selects only `demo.yaml` via +> `spec.source.directory.include`; MetalLB and Longhorn remain unused +> reference manifests, not automatic installs. The demo uses `ClusterIP` +> (an internal-only Service address), reached via port-forward rather than +> a public load balancer. In the steps below, commit and push the changed +> manifests before applying the parent Application, and expect only `demo` +> beneath it. Skip the LAN MetalLB/Longhorn phases for this setup. When +> adding another app later, extend the parent's `include` filter too—for +> example, `'{demo.yaml,new-app.yaml}'`. The three-app walkthrough below +> describes the original LAN template, not this deployment. + This is the last manual step. After this, Git drives everything. ## The idea