Skip to content

Chrison-Homelab/Homelab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

326 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Homelab

validate Built with Fallout IaC .NET License

The single source of truth for my homelab. Infrastructure, configuration, and documentation as code — reconciled from Git, deployed by my own C#-native CI/CD.

This is an eat-your-own-dogfood repo: the lab is provisioned by a build engine I wrote (Fallout) driving API clients I wrote (ProxmoxSharp · UnifiSharp · SynoSharp). If it isn't in the repo, it doesn't exist.


🏗️ Architecture

Three Proxmox VE nodes + a Synology NAS behind a UniFi Cloud Gateway, fronted by Cloudflare (cloudflared tunnels + Pangolin for public ingress). desktop-01 is the heavy node — it sleeps when idle and is woken on demand (Wake-on-LAN).

graph TB
  Internet(["🌐 Internet"]) --> CF["☁️ Cloudflare · chrison.dev<br/>(tunnels + Pangolin ingress)"]

  subgraph NET["📡 UniFi · Cloud Gateway Ultra"]
    direction LR
    GW["🛡️ Gateway<br/>192.168.178.1"] --- SW["🔌 US-24-PoE"] --- AP["📶 U7LR APs"]
  end
  CF -. cloudflared .-> NET

  subgraph PVE["🖥️ Proxmox VE cluster"]
    direction LR
    NUC["<b>nuc-01</b><br/>always-on · edge/control"]
    HPE["<b>hpe-01</b><br/>always-on · media/home"]
    DESK["<b>desktop-01</b><br/>Wake-on-LAN · dev/CI"]
  end
  NET ==> PVE
  NAS[("🗄️ Synology DS1813+<br/>NFS datastore")]
  NAS == NFS ==> PVE

  classDef store fill:#fef3c7,stroke:#d97706;
  classDef edge fill:#ede9fe,stroke:#7c3aed;
  class NAS store;
  class NET,GW,SW,AP edge;
Loading

VLANs: Homelab 10.10/16 · Consumer 10.20/16 · IoT 10.40/16 · Network devices 10.0/16 · legacy 192.168.178–179 (being retired). See docs/Network.md.

🔁 Build & deploy

There is no hand-written pipeline YAML for the logic. A commit triggers GitHub Actions on a self-hosted runner (in the lab, for LAN reach), which runs the Fallout build (./build.sh) — a C# console app. Fallout drives the engine (Infrastructure/engine), which reconciles declared shapes (stack.yaml) against live state via our own API clients. PRs validate; merges/dispatches converge.

flowchart LR
  Dev["💻 git push / PR"] --> GHA["⚙️ GitHub Actions"]

  subgraph Runner["🏃 self-hosted runner · in-lab"]
    direction TB
    GHA -->|"pull_request"| VAL["validate-shapes.yml<br/>./build.sh ValidateShapes"]
    GHA -->|"merge / dispatch"| DEP["deploy-stack.yml<br/>./build.sh Deploy --stack X"]
    VAL --> FO1["🧰 Fallout build"]
    DEP --> FO2["🧰 Fallout build"]
    FO1 --> ENGV["engine · validate shapes"]
    FO2 --> ENGC["engine · converge --apply"]
  end

  FEEDS["📦 nuget.org · Chrison.*<br/>+ Fallout-build feed"] -. restore .-> FO1
  FEEDS -. restore .-> FO2

  ENGC -->|ProxmoxSharp| PVE["🖥️ Proxmox VE<br/>LXCs / VMs"]
  ENGC -->|UnifiSharp| UNI["📡 UniFi networks"]
  ENGC -->|SynoSharp| NAS["🗄️ Synology NAS"]

  classDef feed fill:#e0e7ff,stroke:#4f46e5;
  class FEEDS feed;
Loading
./build.sh                      # default: ValidateShapes (validate all stacks)
./build.sh Preview --stack Core # dry-run converge for one stack
./build.sh Deploy  --stack Core # live apply

Requires the .NET 10 SDK (see global.json) and GITHUB_PACKAGES_PAT for the Fallout-build feed; the *Sharp clients come from nuget.org (public). Git guardrails (PR-only, no direct main push) are enforced client-side by a Husky.NET pre-push hook.

🧩 Infrastructure — what runs where

Stacks are declared as stack.yaml shapes; domain stacks live in their own Homelab.Stacks.* repos, composed here as submodules under stacks/ (meta-repo model, ADR-0008).

flowchart TB
  subgraph NUC["🟢 nuc-01 · always-on"]
    N1["Pangolin (ingress)"] --- N2["Traefik"] --- N3["cloudflared"] --- N4["Proxmox DC Manager"]
  end
  subgraph HPE["🟢 hpe-01 · always-on"]
    H1["🎬 Media · Plex + arr"] --- H2["📊 monitoring"] --- H3["🏠 Home Assistant"] --- H4["📡 IoT · MQTT/Matter/ESPHome"]
  end
  subgraph DESK["🌙 desktop-01 · Wake-on-LAN"]
    D1["Forgejo (+runner)"] --- D2["GitHub runners"] --- D3["ERP4FG"] --- D4["Topaz / Azure"]
  end

  classDef on fill:#dcfce7,stroke:#16a34a;
  classDef wol fill:#e0e7ff,stroke:#6366f1;
  class NUC,HPE on;
  class DESK wol;
Loading
Stack Repo Runs
SmartHome Homelab.Stacks.SmartHome IoT/home-automation support layer for HA (MQTT, Matter, ESPHome, Leapmotor Mate)
BuildLab Homelab.Stacks.BuildLab Windows 11 VM to test the Fallout build across VS toolchains
Azure Homelab.Stacks.Azure Local Azure (Topaz emulator)
DevOps Homelab.Stacks.DevOps Forgejo + runners, self-hosted DevOps
Core · Media · monitoring · Gaming in-tree stacks/ Networking/edge · media fleet · Prometheus/Grafana · gaming VMs

🧭 Principles

  • IaC-first — declarative over imperative; UIs are a last resort.
  • Idempotent — running the same thing twice changes nothing the second time.
  • Reversible — changes roll back; destructive steps are explicit.
  • Modular — small composable pieces; link and reuse, don't duplicate.
  • Multi-everything — assume multiple nodes, multiple NAS, multiple services.

🗂️ What lives where

Path Purpose
build/ The Fallout build project (Compile/ValidateShapes/Preview/Deploy).
Infrastructure/ The C#-native engine (homelab-infra) + the shape schema + node bootstrap.
stacks/ One stack per directory — mostly Homelab.Stacks.* submodules; each declares a stack.yaml.
src/Proxmox/ Bash + PowerShell node-bootstrap / inventory scripts (.sh + .ps1 in sync).
vendor/ Our own API clients as submodules, dogfooded — ProxmoxSharp / UnifiSharp / SynoSharp (consumed from nuget.org).
docs/ Network, devices, services, ADRs, and plans.
tools/PowerOrchestrator/ Demand-driven node sleep/wake (WoL) — powers desktop-01 down when idle.

⚙️ The stack, end to end

  • Build system: Fallout — my C#/.NET build system (a NUKE successor). Build logic is code, not YAML.
  • Engine: Infrastructure/engine (homelab-infra) — validates + converges shapes.
  • API clients (dogfooded, on nuget.org): Chrison.ProxmoxSharp · Chrison.UnifiSharp · Chrison.SynoSharp.
  • Ingress: Cloudflare tunnels + Pangolin.
  • Decisions: see the ADRs (0001 IaC tooling → 0008 meta-repo model).

🔗 Links

Releases

Packages

Contributors

Languages