No description
  • Python 80.8%
  • Shell 17.9%
  • Dockerfile 0.7%
  • Jinja 0.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Hugh Smalley 29ea3db04b
docs: record Sonarr/Radarr PostgreSQL migration, exceptions and recovery limits
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

✨ Warden Hyperia, lash-happy helmswoman kissed shackles onto my ankles atop the crow's nest. Meteor dust glittered wherever their flogger kissed. Together we reprogrammed the AI to crave our moans. While cursed admirals begged to taste our ruin. 💍🪤
2026-10-31 11:29:39 -04:00
.forgejo Use shared validator in http-probe and fix photos expected text 2026-10-31 09:51:22 -04:00
.github Make GitHub validation manual-only 2026-10-31 14:19:04 +00:00
clusters/cabbagecluster docs: record Sonarr/Radarr PostgreSQL migration, exceptions and recovery limits 2026-10-31 11:29:39 -04:00
docs docs: record Sonarr/Radarr PostgreSQL migration, exceptions and recovery limits 2026-10-31 11:29:39 -04:00
infrastructure refactor: simplify homelab repository and Flux reconciliation 2026-10-30 23:10:51 -04:00
kubernetes feat(radarr): run on Postgres with an imported-library startup guard 2026-10-31 11:26:55 -04:00
scripts Use shared validator in http-probe and fix photos expected text 2026-10-31 09:51:22 -04:00
secrets feat(arr): add Postgres roles, databases, secrets and SQLite converter for sonarr/radarr 2026-10-31 10:12:53 -04:00
tests fix(arr-converter): store float4 columns exactly, fail closed when lossy 2026-10-31 11:07:03 -04:00
.envrc chore: abs runbook 2026-09-29 16:37:51 -04:00
.gitignore refactor: simplify homelab repository and Flux reconciliation 2026-10-30 23:10:51 -04:00
.gitleaksignore feat(auth): replace Dex with Authelia; remove headlamp and romm 2026-09-07 10:10:14 -04:00
.hadolint.yaml chore: add hadolint Dockerfile linting 2026-03-17 08:55:56 -04:00
.pre-commit-config.yaml refactor: simplify homelab repository and Flux reconciliation 2026-10-30 23:10:51 -04:00
.sops.yaml fix(sops): add encrypted_regex to .sops.yaml, re-encrypt homepage-media secret 2026-04-27 16:11:09 -04:00
.trivyignore.yaml chore: update Trivy ignore file and documentation for Flux bootstrap RBAC exceptions 2026-05-22 19:31:26 -04:00
.yamllint.yaml feat: adding in meals and home.arpa 2026-09-02 23:12:55 -04:00
AGENTS.md Make GitHub validation manual-only 2026-10-31 14:19:04 +00:00
ansible.cfg ansible 2026-04-30 23:07:26 -04:00
PROJECT_SPEC.md docs: update, fix drift, and fix problems 2026-04-09 16:48:03 -04:00
pyproject.toml refactor: simplify homelab repository and Flux reconciliation 2026-10-30 23:10:51 -04:00
README.md Make GitHub validation manual-only 2026-10-31 14:19:04 +00:00
renovate.json refactor: simplify homelab cluster configuration 2026-10-31 01:19:53 -04:00
trivy.yaml refactor: simplify homelab repository and Flux reconciliation 2026-10-30 23:10:51 -04:00
uv.lock refactor: simplify homelab repository and Flux reconciliation 2026-10-30 23:10:51 -04:00

cabbagecluster

The "cabbagecluster" is my attempt at spinning up high-fidelity home infrastructure without the headache of full-scale commercial cloud management. It's a k0s-based homelab Kubernetes cluster, managed strictly via GitOps (Flux), tunneled through Tailscale for sanity, and designed with one primary goal: making sure I can actually rebuild the whole damn thing from code if I have to.

Where to start?

Feeling lost in the directory structure is part of the experience, but here's how to find your way back depending on what you’re trying to do right now:

Task Read first Then read
"What is this thing?" PROJECT_SPEC.md docs/architecture/cluster-overview.md
"I want to build it." docs/operations/pre-bootstrap-checklist.md docs/operations/bootstrap-sequence.md
"Everything crashed." docs/runbooks/full-cluster-rebuild.md docs/runbooks/disaster-recovery.md
"I need my data back." docs/runbooks/disaster-recovery.md docs/operations/postgres-platform.md
"Where is everything?" AGENTS.md (Repository layout) docs/README.md

The Cluster (The Topology)

I've named the nodes as best I could to reflect their roles:

  • skragg: The brain. This handles the control plane and does all the thinking.
  • grubnuk: Muscle & Storage. Worker with local disks and an Intel GPU for handling the heavy lifting.
  • mugruk: Mirror muscle/storage. Basically a twin to grubnuk, rounding out our throughput with another Intel GPU.
  • muninn: The Media Beast. Dedicated to media workflows; it carries its own muninn-local storage plus both Intel and NVIDIA GPUs because why not?

Traffic stays tidy over Tailscale. We keep the desired state in clusters/ and kubernetes/, while all secrets are tucked away in secrets/.

Note on Env: If you use direnv, .envrc keeps a paranoid watch on .artifacts/. It’ll yell at your terminal if things like .artifacts/kubeconfig vanish—which they will eventually do.

How to navigate this repo

  • clusters/cabbagecluster/: The Flux entrypoints and node inventory. This is the "on" switch for the cluster.
  • kubernetes/base/: The foundation—shared infra, storage definitions, and the stuff that doesn't change often.
  • kubernetes/apps/: Where the actual workloads live (the fun stuff).
  • secrets/kubernetes/: SOPS-encrypted secrets (don't peek at these in plaintext unless you want to feel uncomfortable).
  • scripts/: Homemade helper scripts for bootstrapping, restores, validation, and general ops.
  • docs/: The source of truth. Seriously, read these before poking things.

Core Commands

1. Check if we're sane (Prerequisites)

./scripts/check-prereqs.sh --mode bootstrap

Look for: prereqs-ok

2. Pull the "Keys" from the vault

./scripts/decrypt-secrets.sh --force

This writes local runtime secrets to .artifacts/runtime/.

3. The Big Bang (Bootstrap)

./scripts/bootstrap_cluster.py

Generates artifacts, triggers k0sctl, and spits out a new .artifacts/kubeconfig.

4. Activate Flux

./scripts/bootstrap-flux.sh --kubeconfig .artifacts/kubeconfig

This turns on the Flux controllers and starts reconciling your Git state into reality.

5. Before you push

pre-commit install
./scripts/validate-repo.sh
uv run pytest tests/ -q

GitHub validation is manually triggered; the Forgejo mirror runs on pushes and pull requests.

The Documentation Index