Benjamin · KiyReload · UK
Built, broken, understood.
Written down.
This is my technical workshop: the software I write, the small network of machines I run at home, and the notes I keep so I don’t learn the same lesson twice. Everything below is connected, so start anywhere.
How to read the map. It runs from the physical hardware, through the platform and services built on it, to the projects those made possible, what I wrote about them, and what each one taught me. Selecting something traces what it comes from and what it led to. Line styles show whether a link is hosting, a traffic path, a technology used, or a story; they are not all network cables.
It shows documented architecture, not live status. Nothing on this site reports on a running system.
The network map
Everything on the map, as a list (37)
Hardware
HP Spectre x360Linux Mint laptop
A portable Linux laptop used for college work and remote access.
- Intel Core i7-8565U, 8 GB RAM, 1 TB SSD
- Runs Linux Mint
- Reached with SSH over Tailscale
Connected to
Proxmox serveri5-7500 · 32 GB
The main compute host. It runs the virtual machines and LXC containers, including the Debian media VM.
- Intel Core i5-7500, 32 GB DDR4, 1 GbE
- Storage: 2 × 4 TB HDD, 1 TB HDD, 256 GB M.2, 512 GB SSD
- Only the Debian media VM is documented by name
Connected to
Raspberry Pi 44 GB · always on
A small, separate machine for always-on network services, so DNS keeps working when the Proxmox host is being maintained.
- 4 GB LPDDR4, ARM Cortex-A72
- microSD plus a 500 GB SSD
- Hosts Pi-hole, Unbound, monitoring and dashboards
Connected to
Platform & access
Tailscaleprivate remote access
The private route into the lab and between my own devices, so nothing needs to be opened on the router.
- Documented use: remote SSH into the laptop
- Which other hosts join is not published
- An earlier inventory ran it in an LXC; the current host is not stated
Connected to
Cloudflare Tunnelpublic path
Carries public traffic to the lab through an outbound connection, which avoids opening a port on the router.
- Public website path: Cloudflare Tunnel → Nginx → static files
- Also fronts Jellyfin, behind its login page
- An earlier inventory ran it in an LXC; the current host is not stated
Connected to
Debian media VMowns the ZFS pools
A Debian virtual machine on Proxmox that owns the ZFS storage and runs the media services directly beside it.
- Replaced a TrueNAS VM that served storage over NFS
- The old TrueNAS VM is kept powered off as a rollback
Docker + Portainercontainer workloads
Containers are how most small services run. Portainer is the management view.
- Jellyfin runs as its own Docker service
- An earlier inventory placed Docker and Portainer in a Debian LXC
- Which services are containerised is not itemised publicly
Connected to
Pi-hole + UnboundDNS for the network
Pi-hole answers and filters DNS queries; Unbound is the recursive resolver behind it. Both moved off Proxmox onto the Pi.
- Pi-hole used to run in a Proxmox LXC
- Unbound resolves recursively
Connected to
Services & stack
Rust + TypeScriptcore and interface
The second generation of UMA Companion: a Rust core with a TypeScript/TSX interface, after a Python prototype and a PySide6 version.
- Replaced a CustomTkinter, then PySide6 app
Connected to
SQLitelocal-first state
Holds the catalogue and the user’s own data in separate tables, so a catalogue update can never overwrite a collection.
Connected to
Deck optimiserbeam search
A beam search over six-slot decks that weighs owned and borrowed cards, scenario requirements and interacting effects, then validates the result.
- A heuristic: beam search does not guarantee a global optimum
Connected to
Data packsPlaywright + Actions
Scraping runs as maintainer-side Playwright jobs on GitHub Actions, and ships as data packs instead of bundling a scraper into the app.
Connected to
Astrostatic site builds
This site is built ahead of time into plain files, so the server only has to serve them: no database, no application server.
Connected to
Nginxserves static files
Serves this site’s static files. Requests arrive through the Cloudflare Tunnel.
- An earlier inventory ran it in an LXC; the current host is not stated
Plexlocal ZFS datasets
Reads media from local ZFS datasets. Its config and cache now sit on local storage instead of crossing NFS.
- Existing users, watch history, libraries and metadata were kept
Jellyfintrial beside Plex
Trialled alongside Plex with its own config and cache and read-only media mounts, so the working Plex setup was never at risk.
- Reached through the existing Cloudflare Tunnel, behind a login page
Local ZFSbeside the apps
The storage pools, now owned by the VM that uses them. Both pools were verified before any application paths changed.
- Read-only mounts are not backups; recovery is a separate plan
Connected to
MonitoringBeszel · Uptime Kuma
Beszel for host metrics, Uptime Kuma for availability, and Glances and Dozzle for investigating.
- A July 2026 Beszel snapshot covers Proxmox, the Pi and a Windows machine
- An earlier inventory placed these tools on the Pi; the current overview does not restate it
Connected to
Projects
DNS on the PiActiveactive in the lab
DNS and lightweight services moved from a Proxmox container onto a Raspberry Pi 4, so rebooting the main server no longer takes name resolution with it.
Connected to
Media migrationCompletecomplete · Aug 2026
Moved storage ownership from a TrueNAS VM to a Debian VM without restarting the Plex library, then trialled Jellyfin beside it.
Connected to
This websiteActivestatic pages
A static site served from the lab through a Cloudflare Tunnel. It began as an Eleventy project, was recovered from published HTML, and was redesigned as this connected map.
Connected to
UMA CompanionArchivedarchived · 2025–26
A support-card manager that grew into a local-first desktop ecosystem with a beam-search deck optimiser. Development ended on 18 Aug 2026; the engineering story stays.
Connected to
Writing
Recovering a sitenote · Sep 2026
Take a byte-level baseline first, then separate content from the repeated page shell.
Connected to
UMA retrospectivearticle · Aug 2026
A project that grew from a card manager into a full application, and the decision to stop maintaining it.
Connected to
Moving to Debianarticle · Aug 2026
Consolidating storage and media services onto one Debian VM made the homelab easier to run.
Connected to
Earlier architecturearticle · Jul 2026
The project began as a Python and PySide6 desktop app before its later Rust and TypeScript rebuild.
Connected to
Beszel monitoringarticle · Jul 2026
A lightweight node-based dashboard across Proxmox, a Raspberry Pi 4 and Windows.
Connected to
The Missing Piecearticle · Jul 2026
A dedicated low-power machine for always-on DNS and services.
Connected to
First Markdown postnote · Jul 2026
Why the previous version of this site moved to Markdown, and how it was built and deployed.
Connected to
Lessons
Validate resultsevidence, not looks
A convincing optimisation result still needs evidence. Explainable scoring and validation exist so a plausible answer is never mistaken for a correct one.
Connected to
Data boundariescatalogue vs. user
An early database update could overwrite user data. Separating catalogue tables from user tables made the boundary safe, and uncertain OCR input needs the same explicit treatment.
Connected to
Architecture by userewrites can pay off
Architecture becomes clear through use, so a rewrite that captures earlier lessons can be worth it.
Connected to
Knowing when to stopa product decision
When maintenance cost outweighs remaining value, ending a project can be the sound product decision. Finished work stays documented.
Connected to
Baseline firstprove nothing changed
Before redesigning something you only have the output of, snapshot it, hash it and rebuild it until it matches. Then change things.
Connected to
Reversible stepsrollback first
Stage the move, verify before changing paths, and keep the old system powered off but intact until the new one has proved itself.
Connected to
Storage ownershipfewer boundaries
A dedicated NAS is not wrong. Here, letting the VM that uses the storage also own it removed a whole class of permission problems.
Connected to
Placement mattersas much as how
Where a service runs can matter as much as how it runs. Independent hardware shrinks what a maintenance window can affect; it is not redundancy and not a backup.
Connected to
Three ways in
Pick a thread
Software
Tools built to solve a problem. The main one, UMA Companion, grew for a year, taught a lot about data boundaries, and was retired on purpose.
Read the case study →Systems
A Proxmox server, a Raspberry Pi, a media stack and the access layer around them, drawn as the documentation describes it.
Tour the homelab →Writing
Migrations, retrospectives and fixes I want to remember, written to be read start to finish without distractions.
Open the notebook →Recently
What changed
Where to go next
Follow a request
The network page steps through how a visitor reaches this site, how a DNS lookup is answered at home, and how I get back in privately, one hop at a time, with the private details left out on purpose.