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 | |
|---|---|
| Model | Lenovo ThinkPad P15v Gen 3 |
| OS | [[nixos |
| Desktop | KDE Plasma |
| CPU | Intel Core i7-12700H, 14 cores / 20 threads |
| GPU | NVIDIA RTX A2000 4 GB with hybrid graphics; disabled by default for battery life |
| Memory | 32 GB DDR4 |
| Storage | Approximately 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 | |
|---|---|
| Model | 16-inch MacBook Pro (2024) |
| CPU | Apple M4 |
| Memory | 48 GB |
| Storage | 256 GB |
I keep employer-owned equipment as a compact note here; company systems and internal tooling are intentionally outside this inventory.
Desk and peripherals
| Category | What I use |
|---|---|
| Keyboard | Ducky Mecha Mini Creator Edition |
| Microphone | Blue Yeti |
| Webcams | Logitech C930e, Logitech C170 |
| Audio | AirPods Pro (2nd generation), Apple EarPods |
| Displays | 32-inch AOC 1080p 120 Hz; two 27-inch Samsung LF27T35 1080p 75 Hz displays |
Mobile gear
| Category | What I use |
|---|---|
| Phone | Apple iPhone 17 Pro Max |
| Cellular | Verizon — approximately $35/month |
Making and 3D printing
Elegoo Centauri Carbon — ecc
| Specification | Value |
|---|---|
| Model | Elegoo Centauri Carbon |
| Build volume | 256 × 256 × 256 mm |
| Motion | CoreXY, fully enclosed |
| Print speed | Up to 500 mm/s |
| Acceleration | Up to 20,000 mm/s² |
| Hot end | Up to 320°C |
| Bed | Up to 110°C |
| Slicer | OrcaSlicer |
Software workflow
Daily drivers
| Job | Tool |
|---|---|
| Editor | Neovim |
| Terminal | Konsole and Yakuake |
| Shell | Zsh + Starship |
| Browser | Firefox, synced through my own Firefox Sync server |
| File manager | Dolphin and lf |
| Notes | Obsidian and Apple Notes |
| Passwords | Bitwarden |
| Git | Git, 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
| Group | Tools |
|---|---|
| Navigation | fzf, zoxide, lf |
| Inspection | bat, eza, fd, ripgrep, jq |
| Sessions and processes | tmux, bottom |
| Environments | Nix, direnv, nix-direnv |
| Containers and VMs | Podman (with a Docker-compatible socket), libvirt |
| Everyday utilities | curl, rsync, ImageMagick |
Development
| Category | Tools |
|---|---|
| Languages and runtimes | Bun, Node.js, Go, Rust and Cargo |
| Editors and IDEs | Neovim |
| Coding agents | Claude Code, Pi, herdr for running agents in terminal panes |
| Personal agents | os, my own persistent agent, and Hermes Agent, both on europa with MCP access to my services |
| Desktop tools | Obsidian, 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.
| Host | Hardware | What it does |
|---|---|---|
charon | Hetzner VPS | Mesh coordinator, public edge, this website, outside health checks, alerts |
io | Ryzen 5 5600X, 32 GB DDR4 | Sign-in (Kanidm), Forgejo, CI, the binary cache, Vaultwarden, Home Assistant, and smaller apps |
titan | Intel i5-8400, 64 GB DDR4, ZFS and bcachefs pools | Storage, backups, monitoring and alerting, documents, photos, media |
europa | Ryzen 5 7600X, 32 GB DDR5, NVIDIA RTX 4070 Ti 12 GB | Local AI models, AI agents, my dev environment, the 3D printer’s MCP server |
phobos, deimos, styx | Repurposed small-form-factor systems | Remote Nix builders and Forgejo Actions runners |
callisto | ThinkPad P15v Gen 3 | Workstation 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.
| Area | Highlights |
|---|---|
| Identity and security | Kanidm, Vaultwarden, Headscale |
| Documents and photos | Paperless-ngx, Immich with machine learning on the GPU |
| Development and CI | Forgejo, nixbot, Forgejo Actions, Harmonia binary cache, Renovate, Wakapi, IT-Tools |
| AI and agents | llama-swap (chat, image, video, speech), InvokeAI, os, Hermes Agent, Executor |
| Home and search | Home Assistant, SearXNG, Firefox Sync |
| Observability | OpenTelemetry Collector, VictoriaMetrics, VictoriaLogs, VictoriaTraces, Grafana, Gatus, ntfy, Umami |
| Media | Jellyfin, 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.
| Utility | Current choice | Approximate cost |
|---|---|---|
| Internet | AT&T Fiber, 1 Gbps | $90/month |
| Cellular | Verizon | $35/month |
| Electricity | Georgia Power | $0.20/kWh |
| DNS and domains | Cloudflare | $50/year |
| Hosting | Primarily the machines and services above | Varies |
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
| Specification | Value |
|---|---|
| CPU | Intel i5-10210U, 4 cores / 8 threads |
| GPU | Integrated Intel UHD |
| Memory | 16 GB DDR4 |
| Storage | 500 GB NVMe SSD |
15-inch Intel MacBook Pro (2019) — unused, broken display
| Specification | Value |
|---|---|
| CPU | Intel i7-9750H, 6 cores / 12 threads |
| GPU | Integrated Intel UHD 630 |
| Memory | 16 GB DDR4 |
| Storage | 512 GB SSD |
Raspberry Pi 3B+ — former proxy host
| Specification | Value |
|---|---|
| CPU | Broadcom BCM2837B0, 4 cores |
| Memory | 1 GB LPDDR2 |
| Storage | 128 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
| Category | Past uses |
|---|---|
| Browsers | Helium, Google Chrome, Brave, Thorium, Microsoft Edge, Chromium, Arc, Zen Browser, Firefox Developer Edition, Safari, Orion |
| Editors and terminals | Zed, VS Code, Brackets, Kitty, Ghostty |
| Coding agents | OpenCode, Codex, Amp |
| Desktop environments and window managers | Hyprland with DankMaterialShell, GNOME, COSMIC, XFCE, niri, herbstluftwm, i3, bspwm |
| Launchers and desktop shells | Vicinae, Walker, Rofi, dmenu, Waybar, Polybar, Mako, SwayNotificationCenter, Dunst |
| Linux distributions | Ubuntu, Antergos, EndeavourOS, Garuda, Archcraft, Manjaro, Nobara, CentOS, Rocky Linux, AlmaLinux |
| Self-hosted services | CommaFeed, Glance, Gitea, ownCloud, Mailpit, Jellystat, Jellyseerr, PhotoPrism, Miniflux, Paperless-AI, OpenClaw, Rybbit, Beszel |
| Infrastructure | NetBird 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 carriers | Visible |
| Hosting platforms | GitHub Pages, Cloudflare Pages, Railway, Fly.io, Google Cloud Run, AWS EC2 |
| Other tools | Bash as the primary shell, Ranger, htop, Docker Engine, 1Password, Homebrew, Raycast, FreeCAD |