I’ve been fascinated by computers for as long as I can remember. I tried building them before my first Lego set and browsed GitHub years before I understood a line of code.

This is the hardware, software, and infrastructure I use now: part setup tour, part living inventory, and part record of how my tools have changed. I favor things I can understand, shape, and keep running myself.

Homelab overview

Access and name resolution

flowchart LR
  devices["My devices<br/>laptop and phone"]
  public["Public visitors"]

  subgraph mesh["Private Headscale mesh"]
    dns["Mesh DNS<br/>names generated from platform"]
    nginx["nginx on each host<br/>sign-in through Kanidm"]
  end

  edge["charon (VPS)<br/>mesh coordinator, public edge,<br/>status checks, alerts"]
  apps["Services on io, titan, europa"]

  devices --> mesh
  dns --> nginx
  nginx --> apps
  public --> edge
  edge -->|the few public names, over the mesh| nginx

Every machine and my personal devices join one Headscale mesh using Tailscale clients. The mesh’s DNS answers service names with records generated from platform’s inventory, so almost everything I run can only be reached on the mesh. A small VPS is the public edge. It forwards the handful of public names home over the mesh without decrypting them, and also serves this site, so the site stays up when home is down.

Infrastructure and data lifecycle

flowchart TB
  me["Workstation<br/>callisto"]
  forge["Forgejo + nixbot CI<br/>io"]

  subgraph builders["Build capacity"]
    lab["phobos / deimos / styx<br/>remote builders, Actions runners"]
    cache["Binary cache<br/>io"]
  end

  subgraph hosts["Every host"]
    comin["comin pulls the reviewed branch<br/>builds and switches itself"]
    otel["OpenTelemetry Collector<br/>metrics, logs, traces"]
    restic["Nightly restic backup<br/>of persisted state"]
  end

  subgraph titan["titan (NAS)"]
    monitor["VictoriaMetrics, Logs, Traces<br/>Grafana, vmalert"]
    repo["restic server<br/>on ZFS tank"]
  end

  b2["Backblaze B2<br/>offsite, from a ZFS snapshot"]
  ntfy["ntfy alerts<br/>charon"]
  gatus["Gatus<br/>outside health checks"]

  me -->|pull request| forge
  forge --> builders
  forge --> comin
  otel --> monitor
  restic --> repo
  repo -->|nightly| b2
  monitor --> ntfy
  gatus --> ntfy

Changes start as pull requests. nixbot builds every host and runs a VM test for each service before anything merges, and then each machine pulls the result and switches itself. The NAS holds storage, monitoring, and backups: every host backs up its persisted state nightly, and the whole ZFS pool goes to Backblaze B2 from one consistent snapshot, with a monthly prune and sampled integrity check. Gatus runs on the VPS, so it still reports an outage even if the NAS is down.

Everything runs NixOS and is described in platform. These diagrams show roles and flows. Addresses, ports, credentials, and security boundaries are left out because they don’t belong on a public page.

Why NixOS and platform?

I want a setup I can rebuild, review, and improve instead of a collection of machines I am afraid to touch. NixOS gives me reproducible hosts. kuhree.com/platform turns that into a shared inventory, service model, deployment workflow, and record of why the system looks the way it does.

Primary workstation

ThinkPad P15v Gen 3 — callisto

Current setup
ModelLenovo ThinkPad P15v Gen 3
OS[[nixos
DesktopKDE Plasma
CPUIntel Core i7-12700H, 14 cores / 20 threads
GPUNVIDIA RTX A2000 4 GB with hybrid graphics; disabled by default for battery life
Memory32 GB DDR4
StorageApproximately 1 TB NVMe

This is where I write and operate the homelab. Heavy development runs on europa, the GPU server, and the laptop acts as a thin client to it. Plasma is configured declaratively from platform, like everything else.

Work computer

Current setup
Model16-inch MacBook Pro (2024)
CPUApple M4
Memory48 GB
Storage256 GB

I keep employer-owned equipment as a compact note here; company systems and internal tooling are intentionally outside this inventory.

Desk and peripherals

CategoryWhat I use
KeyboardDucky Mecha Mini Creator Edition
MicrophoneBlue Yeti
WebcamsLogitech C930e, Logitech C170
AudioAirPods Pro (2nd generation), Apple EarPods
Displays32-inch AOC 1080p 120 Hz; two 27-inch Samsung LF27T35 1080p 75 Hz displays

Mobile gear

CategoryWhat I use
PhoneApple iPhone 17 Pro Max
CellularVerizon — approximately $35/month

Making and 3D printing

Elegoo Centauri Carbon — ecc

SpecificationValue
ModelElegoo Centauri Carbon
Build volume256 × 256 × 256 mm
MotionCoreXY, fully enclosed
Print speedUp to 500 mm/s
AccelerationUp to 20,000 mm/s²
Hot endUp to 320°C
BedUp to 110°C
SlicerOrcaSlicer

Software workflow

Daily drivers

JobTool
EditorNeovim
TerminalKonsole and Yakuake
ShellZsh + Starship
BrowserFirefox, synced through my own Firefox Sync server
File managerDolphin and lf
NotesObsidian and Apple Notes
PasswordsBitwarden
GitGit, Delta, and lazygit

Neovim over SSH

Neovim is the default editor because it is fast, composable, and equally at home over SSH, which matters when the real work happens on another machine.

Shell and terminal tools

GroupTools
Navigationfzf, zoxide, lf
Inspectionbat, eza, fd, ripgrep, jq
Sessions and processestmux, bottom
EnvironmentsNix, direnv, nix-direnv
Containers and VMsPodman (with a Docker-compatible socket), libvirt
Everyday utilitiescurl, rsync, ImageMagick

Development

CategoryTools
Languages and runtimesBun, Node.js, Go, Rust and Cargo
Editors and IDEsNeovim
Coding agentsClaude Code, Pi, herdr for running agents in terminal panes
Personal agentsos, my own persistent agent, and Hermes Agent, both on europa with MCP access to my services
Desktop toolsObsidian, Bitwarden, LocalSend, OrcaSlicer

The list above reflects the tools configured in platform’s dev environment, not every language or application I have ever tried.

Homelab machines and services

Compute and storage

Hosts are named after the moons of Jupiter and Mars. The VPS is named for the ferryman.

HostHardwareWhat it does
charonHetzner VPSMesh coordinator, public edge, this website, outside health checks, alerts
ioRyzen 5 5600X, 32 GB DDR4Sign-in (Kanidm), Forgejo, CI, the binary cache, Vaultwarden, Home Assistant, and smaller apps
titanIntel i5-8400, 64 GB DDR4, ZFS and bcachefs poolsStorage, backups, monitoring and alerting, documents, photos, media
europaRyzen 5 7600X, 32 GB DDR5, NVIDIA RTX 4070 Ti 12 GBLocal AI models, AI agents, my dev environment, the 3D printer’s MCP server
phobos, deimos, styxRepurposed small-form-factor systemsRemote Nix builders and Forgejo Actions runners
callistoThinkPad P15v Gen 3Workstation and thin client to europa

Self-hosted highlights

The durable inventory lives in platform. This public page keeps only the stable shape so normal service changes do not turn it into a stale second inventory.

AreaHighlights
Identity and securityKanidm, Vaultwarden, Headscale
Documents and photosPaperless-ngx, Immich with machine learning on the GPU
Development and CIForgejo, nixbot, Forgejo Actions, Harmonia binary cache, Renovate, Wakapi, IT-Tools
AI and agentsllama-swap (chat, image, video, speech), InvokeAI, os, Hermes Agent, Executor
Home and searchHome Assistant, SearXNG, Firefox Sync
ObservabilityOpenTelemetry Collector, VictoriaMetrics, VictoriaLogs, VictoriaTraces, Grafana, Gatus, ntfy, Umami
MediaJellyfin, RomM, Seerr, and the Arr apps that still earn their place

Self-hosting is less about collecting applications than choosing where my data lives and learning how the pieces behave together. The useful services come first; the infrastructure exists to make them dependable.

Utilities and recurring costs

Costs are approximate snapshots, included because this page is also an inventory for future me.

UtilityCurrent choiceApproximate cost
InternetAT&T Fiber, 1 Gbps$90/month
CellularVerizon$35/month
ElectricityGeorgia Power$0.20/kWh
DNS and domainsCloudflare$50/year
HostingPrimarily the machines and services aboveVaries

Past Uses

Good tools change, machines get repurposed, and experiments end. This is the compact history behind the current setup.

Former computers

ThinkPad E15 — unused, no longer charging

SpecificationValue
CPUIntel i5-10210U, 4 cores / 8 threads
GPUIntegrated Intel UHD
Memory16 GB DDR4
Storage500 GB NVMe SSD

15-inch Intel MacBook Pro (2019) — unused, broken display

SpecificationValue
CPUIntel i7-9750H, 6 cores / 12 threads
GPUIntegrated Intel UHD 630
Memory16 GB DDR4
Storage512 GB SSD

Raspberry Pi 3B+ — former proxy host

SpecificationValue
CPUBroadcom BCM2837B0, 4 cores
Memory1 GB LPDDR2
Storage128 GB SD card and 3.5 TB hard drive

Former gear

  • Cheapino v2 keyboard
  • Truthear Zero IEMs
  • iPhone XS, OnePlus 7 Pro, and OnePlus N200

Former software and services

CategoryPast uses
BrowsersHelium, Google Chrome, Brave, Thorium, Microsoft Edge, Chromium, Arc, Zen Browser, Firefox Developer Edition, Safari, Orion
Editors and terminalsZed, VS Code, Brackets, Kitty, Ghostty
Coding agentsOpenCode, Codex, Amp
Desktop environments and window managersHyprland with DankMaterialShell, GNOME, COSMIC, XFCE, niri, herbstluftwm, i3, bspwm
Launchers and desktop shellsVicinae, Walker, Rofi, dmenu, Waybar, Polybar, Mako, SwayNotificationCenter, Dunst
Linux distributionsUbuntu, Antergos, EndeavourOS, Garuda, Archcraft, Manjaro, Nobara, CentOS, Rocky Linux, AlmaLinux
Self-hosted servicesCommaFeed, Glance, Gitea, ownCloud, Mailpit, Jellystat, Jellyseerr, PhotoPrism, Miniflux, Paperless-AI, OpenClaw, Rybbit, Beszel
InfrastructureNetBird and CoreDNS (replaced by Headscale), ZITADEL (replaced by Kanidm), agenix (replaced by sops-nix), Docker Swarm, Grafana Mimir, Loki, Tempo, and Alloy (replaced by OpenTelemetry and the Victoria stack)
Mobile carriersVisible
Hosting platformsGitHub Pages, Cloudflare Pages, Railway, Fly.io, Google Cloud Run, AWS EC2
Other toolsBash as the primary shell, Ranger, htop, Docker Engine, 1Password, Homebrew, Raycast, FreeCAD