Profile
Back to NewsBack
GitHub Trending 8 min
Reader Mode
mortennordbye/homelab: GitOps-managed homelab using Kubernetes (Talos), ArgoCD, and Terraform for infrastructure as code.

mortennordbye/homelab: GitOps-managed homelab using Kubernetes (Talos), ArgoCD, and Terraform for infrastructure as code.

7 hours ago

Drawn every 15 minutes from nordbye.it/api/v1/infra, which a CronJob fills from the Kubernetes API and Prometheus. When the cluster is unreachable the card says so.

Documentation

Read the docs at docs.nordbye.it</a>

Everything in this repo is documented at docs.nordbye.it: how the parts fit together, and how to operate or rebuild each one.

The site is built from docs/ on every push to main, so it always matches this repo.

Writing

Longer write-ups of things built in this repo, on blog.nordbye.it:


Quick Links

Portfolio</a> Blog</a> Docs</a> LinkedIn</a> GitHub</a>

Feel free to send me a DM, open a pull request, or steal code from here. The goal is to learn and make connections.


How It Works

Terraform builds the Talos VMs on Proxmox. Everything after that arrives through git.

push to main
   ├─ GitHub Actions builds portfolio and blog, pushes to GHCR
   │     └─ Kargo promotes stage to prod as a pull request you merge
   └─ Argo CD reconciles k8s/talos/** onto the cluster
         ├─ External Secrets fetches credentials at runtime, so none are committed
         ├─ Traefik publishes routes through Gateway API, cert-manager and external-dns handle TLS and DNS
         └─ KEDA lets idle apps drop to zero; the HTTP interceptor wakes them on the first request

Argo CD runs two ApplicationSets in k8s/talos/infra/argocd/ that generate one Application per directory, so a new workload is a new directory.


Homelab Overview

Homelab Overview</a>

Click to open the full-size image. A map of the whole homelab — how the hardware, cluster and services fit together. Auto-generated through the pipeline from this file.

Network & Service Flow

Network & Service Flow</a>

Click to open the full-size image. Shows which services talk to each other and how traffic flows through the cluster. Auto-generated through the pipeline from this file.

Repository Structure

Note: This is a simplified view showing the main folders and key files. The actual repository contains additional directories and configurations.
homelab
├── k8s/talos/
│   ├── apps/                            # Application deployments
│   │   ├── arr-stack/
│   │   ├── blog/
│   │   └── plex-media-stack/
│   └── infra/                           # Infrastructure components
│       ├── argocd/
│       ├── cilium/
│       └── traefik/
├── terraform/
│   ├── azure/
│   │   └── state/                       # Remote state backend
│   └── proxmox/                         # Proxmox cluster IaC
│       └── hyper-cluster/
│           └── k8s/
├── blog/                                # Hugo blog source
│   ├── Dockerfile
│   ├── config/
│   ├── content/
│   └── themes/
├── portfolio/                           # Portfolio site source
│   ├── Dockerfile
│   ├── nginx/
│   └── src/
├── docs/                                # Technical docs, published to docs.nordbye.it
│   ├── architecture/
│   ├── platform/
│   ├── apps/
│   └── backlog/
└── ai/                                  # AI agents, skills, projects, local LLM
    ├── agents/
    ├── skills/
    ├── projects/
    ├── local-llm/
    ├── prompts/
    └── notes/

Kubernetes Tech Stack

| Category | Components | | --- | --- | | GitOps | Argo CD (ApplicationSets), Kargo (stage to prod promotion for blog, headroom, logeverylift, portfolio, reelsmith and verksted), Argo Rollouts (installed, no workload uses it yet) | | Networking | Cilium (CNI, eBPF, L2 announcements and LB IPAM), Traefik via Gateway API, external-dns (Cloudflare) | | Security | Falco (runtime, modern eBPF probe), Authentik (SSO), cert-manager, External Secrets Operator (Bitwarden Secrets Manager, pattern) | | Observability | Prometheus and Alertmanager, Grafana, Loki (logs), Tempo (traces), metrics-server | | Scaling | KEDA with the HTTP add-on: nine apps drop to zero replicas and the interceptor wakes them on the first request | | Automation | Reloader (config and secret triggered rollouts) | | Storage | Proxmox CSI (block), csi-driver-nfs (Synology NFS) | | Databases | PostgreSQL 18 (in-cluster, NFS-backed, behind logeverylift) | | Platform | Proxmox VE on three Lenovo nodes, Talos Linux (three control plane and three worker VMs), Terraform |


Security

Container Vulnerability Scanning

Automated vulnerability scanning runs weekly and on every Dockerfile change using Trivy. Scans detect CRITICAL and HIGH severity vulnerabilities in both blog and portfolio containers, with results automatically uploaded to GitHub Security tab for tracking and remediation.

Runtime Security

Falco runs as a DaemonSet on every node, detecting anomalous activity at the syscall level through a modern eBPF probe (the Talos-safe driver — no kernel module). Detections are routed to Discord via Falcosidekick, false positives are tuned out using the upstream rules' own template macros (keeping signal high), and Falco metrics feed a Grafana dashboard for at-a-glance security visibility.


CI/CD Workflows

| Workflow | Trigger | Purpose | | --------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------ | | Build and Deploy Blog | Push to main and pull request (blog changes) | Lints and builds the Hugo blog; on main pushes to GHCR (Kargo promotes stage → prod) | | Build and Deploy Portfolio | Push to main and pull request (portfolio changes) | Lints, typechecks and builds the image; smoke tests it on PRs, pushes to GHCR on main (Kargo promotes stage → prod) | | Container Vulnerability Scan | Sundays, prod promotion, manual | Scans the blog and portfolio images prod runs with Trivy, CRITICAL and HIGH with a fix available | | Render Assets | Push to main (docs/assets/diagrams/*.d2, docs/assets/logo/source.jpg), manual | Renders D2 sources to SVG + PNG and re-crops the logo, commits the result | | Reminders | Monthly (1st, 8th, 15th), manual | Discord reminders for Kubernetes upkeep, backups, and server updates | | Dependency Review | PR | Blocks pull requests that add known-vulnerable dependencies | | Scorecard | Mondays 03:00 UTC, manual | OpenSSF supply chain score, published to the Security tab | | README Cards | Every 15 minutes, manual | Redraws the cluster card at the top of this page and the star chart at the foot of it | | Kargo Automerge | Kargo promotion PR | Merges promotion PRs for the apps listed in KARGO_AUTOMERGE_APPS, where the canary is the real gate | | Lighthouse | Mondays 06:00 UTC, manual | Audits the live public sites, median of 3 runs, gating SEO, accessibility and best practices | | Docs Site | Push to main (docs/** and the site config), pull request, manual | Builds docs/ with ProperDocs in strict mode and publishes it to docs.nordbye.it |


Hardware

Compute Nodes

| Node | Model | CPU | RAM | Storage | | ------ | ----------------------------- | ---------------------------------------- | ----- | ------- | | Hyper1 | Lenovo ThinkCentre M70q Gen 2 | Intel Core i5-11400T (6C/12T @ 1.30 GHz) | 32 GB | 1 TB | | Hyper2 | Lenovo ThinkCentre M920q | Intel Core i5-8500T (6C/6T @ 2.10 GHz) | 32 GB | 1 TB | | Hyper3 | Lenovo ThinkCentre M920 Tiny | Intel Core i7-8700T (6C/12T @ 2.40 GHz) | 32 GB | 1 TB |

Proxmox Setup Scripts

Community Proxmox VE Helper-Scripts run on each node after install:

| Script | Purpose | | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | Post PVE Install | Post-install tuning — repo sources, subscription nag, updates | | NIC Offloading Fix | Disables NIC hardware offloading to fix interface connectivity issues |

Storage

| Device | Model | CPU | RAM | Capacity | Details | | ------ | ---------------- | ------------------------------ | ---- | ---------------- | ------------------------------------------------------------------------------------ | | NAS | Synology DS1522+ | AMD Ryzen R1600 (2C @ 2.6 GHz) | 8 GB | 3 × 20TB (60TB) | SHR, Btrfs, 2 × 1TB NVMe cache · DSM 7.3.2 · hosts a Proxmox Backup Server (PBS) VM |

Network Equipment

| Device | Model | Type | | ------------ | ------------------- | -------------- | | Router | UniFi Cloud Gateway | Gateway/Router | | Switch | UniFi Lite 8 PoE | Managed Switch | | Switch | UniFi Flex Mini | Managed Switch | | Access Point | UniFi U6+ | WiFi 6 AP | | Modem | Telia | Cable Modem |

IoT & Smart Home

Home Assistant Server

| Component | Model | CPU | RAM | Storage | OS | Network | | --------- | --------------------------- | ---------- | --- | ---------- | ------------------ | --------------- | | Hardware | Topton N100 Fanless Mini PC | Intel N100 | TBD | 512 GB SSD | Home Assistant OS | 4 × 2.5G i226-V |

Devices

| Device | Type | Purpose | | ---------------------------------------------- | ----------------------- | ------------------------------------- | | Philips Hue Bridge Pro | Smart Lighting Hub | Lighting control | | Nabu Casa Connect ZBT-2 | Zigbee Coordinator | Zigbee device coordination | | M5Stack Atom Lite | Bluetooth Proxy | Bluetooth range extension | | UniFi G6 Instant | Security Camera | Indoor surveillance | | Nabu Casa Home Assistant Voice Preview Edition | Voice Satellite | Voice control (ESPHome, Wi-Fi) | | Aqara T1 Temperature and Humidity Sensor | Zigbee Climate Sensor | Indoor temperature and humidity (ZHA) | | Aqara Vibration Sensor T1 | Zigbee Vibration Sensor | Vibration and tilt detection (ZHA) | | Aqara T1 Door and Window Sensor | Zigbee Contact Sensor | Door and window open/closed (ZHA) | | Aqara T1 Water Leak Sensor | Zigbee Leak Sensor | Water leak detection (ZHA) |


Other Projects

A few other things I build and self-host outside this repo:

| Project | Description | Stack | | ------- | ----------- | ----- | | logeverylift | Mobile-first workout tracking PWA | Next.js 16, PostgreSQL 18, Drizzle | | lawless-waf | Tune Azure WAF false positives without paying Log Analytics prices | Python, React, Terraform | | headroom | Self-hosted personal finance tracker for budgets, assets, investments, and loan modeling | TypeScript, SQLite, Docker |


Star this repo if it is useful to you

Star history: cumulative stars over time, with the last 30 days, the last 7 days, and the busiest single day

Made by Morten Victor Nordbye

Chat with me