Homelab & Self-Hosted Infrastructure

The systems side of this site isn't a diagram on a slide. It's a running homelab I own end to end, from the physical layer up: an OPNsense router and a VLAN-segmented network, a TrueNAS box with a redundant ZFS pool, several Linux machines, and the actual wiring between them. Source control, files, media, chat and social all run on that hardware in Docker Compose, exposed to the internet the hard way. On top of it sits something less common: a self-hosted, local-model AI platform spread across multiple machines, driving an agent over my own LLM, image, video, speech and 3D models with no third-party API in the loop. This is the same architecture-through-deployment ownership I bring to client work, applied to my own stack.

The edge: a reverse WireGuard tunnel

The home lab never exposes its own IP. Instead, a small rented node acts as an edge ingress: it holds the public IP and the DNS records, and forwards traffic to the lab over a WireGuard tunnel that the lab dials outbound. Nothing at home listens on a public address, so the residential IP never leaks. And if the edge ever takes abuse, it's a disposable lever I can null-route or rebuild without touching a single service.

🌐 Public internet HTTPS Edge node public IP · TLS WireGuard peer WireGuard tunnel lab dials out Home lab · Docker GitLab Nextcloud Jellyfin Mastodon Matrix + internal no public IP · reverse proxy monitoring · backups

The network: OPNsense, VLANs and real wires

Behind the tunnel is a network I run myself, not an ISP box with an admin page I'm locked out of. Routing and firewalling are handled by an OPNsense router that I configure and maintain, and the LAN is carved into multiple VLANs: the servers sit on one segment, trusted personal devices on another, and untrusted gear on its own island. Firewall rules decide exactly what is allowed to cross between them, so when a smart-anything misbehaves, the worst it can reach is its own little corner.

The physical layer is mine too. Every machine in this writeup hangs off switching and cable runs I put in myself, with VLANs tagged across the trunks. When a link goes flaky there's no help desk to call; tracing it back to a port, a cable or a NIC is part of the job.

🌐 WAN OPNsense router · firewall inter-VLAN rules trunk Switching tagged VLANs Servers Docker host · TrueNAS · AI rigs Trusted devices workstations · personal gear Untrusted IoT & guests, firewalled off

Storage: TrueNAS and ZFS

Bulk storage lives on a dedicated TrueNAS box running a redundant ZFS pool. ZFS checksums every block, scheduled scrubs walk the whole pool looking for silent corruption, and snapshots give me point-in-time rollback before I trust any risky change. Managing it is a real, ongoing job: pool layout, disk health, capacity planning, and the occasional resilver when a drive starts throwing errors.

The NAS is also the backbone of the backup story. Services on the Docker host back up to it on a schedule, snapshots keep history, and a second copy still leaves the building, because redundancy inside one chassis is not a backup. Losing a disk here is an errand, not an event.

What's running

Thirty-odd containers, each defined in its own Docker Compose project, behind a reverse proxy that terminates TLS and routes each subdomain. A few of these back the links elsewhere on this site; most are just how I choose to own my own data. The AI platform gets its own section below.

Federated & social

Source control

GitLab

Self-hosted Git for my own projects and infrastructure-as-code, with issue tracking and CI/CD.

Fediverse

Mastodon

A personal Mastodon instance on the ActivityPub fediverse, my own corner of decentralised social.

Messaging

Matrix

My own Matrix homeserver on the federated chat network. This is the @luke:computingcache.com you can message me at.

@luke:computingcache.com
Decentralised

Nostr relay

My own Nostr relay on the network, accepting and rebroadcasting signed events, so I'm not renting a seat on someone else's relay.

Files & personal

Personal · private

Nextcloud

Files, calendar and contacts: my own Google-Drive replacement, synced across devices and shared on my terms.

Personal · private

PhotoPrism

A self-hosted photo library with on-device tagging and search. It's Google Photos without handing Google the photos.

Personal · private

Trilium

A hierarchical notes and knowledge base: my second brain, versioned and mine, not a subscription.

Personal · private

Monica

A personal CRM: who I know, how we're connected, what we last talked about. Relationships kept off other people's servers.

Personal · private

Grocy

Groceries, stock and household chore tracking: the “ERP for your fridge”, self-hosted.

Media libraries

Personal · private

Jellyfin

A media server for my own film and TV library, streamed to any device without a subscription or a third party in the middle.

Personal · private

Calibre

An e-book library and reader server: my whole collection, organised and readable from anywhere.

Personal · private

GameVault · Retrom

Self-hosted game libraries: a “Steam for DRM-free games” backend plus a retro/emulation collection, streamed to my own clients.

Personal · private

LANraragi

A tagged, searchable archive server for a large comic/manga collection.

Knowledge & archival

Personal · private

ArchiveBox

A self-hosted web archive: anything I bookmark is snapshotted to HTML, screenshot and WARC, so link-rot can't touch it.

Personal · private

HTTrack

On-demand full-site mirroring: pull an entire site down for offline reading or preservation.

Personal · private

Kiwix

Offline Wikipedia and other ZIM knowledge bases: the reference internet, served from my own disk even if the real one is gone.

Personal · private

LanguageTool

A private grammar and style server for my own writing, spell-check that doesn't ship my prose to a cloud vendor.

Operations, privacy & the boring bits

Behind the scenes

Prometheus + Grafana

Metrics scraping and dashboards for every host and container: the panes of glass I actually watch.

Behind the scenes

Matomo

Privacy-first, self-hosted web analytics. I get the numbers without feeding a third party a tracker.

Behind the scenes

I2P

A node on the I2P anonymising network, self-hosting on the darknet as well as the clearnet.

Behind the scenes

XBackBone

A self-hosted screenshot and file host with a ShareX endpoint: my own image-sharing short-links.

Behind the scenes

Ops & access

Automated offsite backups, WireGuard for remote access, and network-wide ad-blocking DNS: the parts that keep the rest healthy.

The AI platform: “Task Studio”

This is the part I'm proudest of. On top of the homelab runs a self-hosted, agentic AI platform: a private console I call Task Studio that turns a plain-English request into a finished deliverable, whether that's a researched report, a small website, generated images, or a fully narrated, scored and captioned marketing video. Every model runs on my own hardware. There is no OpenAI, no Anthropic, no third-party API anywhere in the loop. The LLM that reasons, the diffusion models that render, the voice that narrates, and the model that turns an image into a 3D mesh are all local.

It started as something smaller: a worker for an online task marketplace (built with the platform operator's permission) that polls open bounties, uses a local model to judge which are genuinely AI-suitable, drafts a proof, routes it through a human-review queue, and submits it. That pipeline of classify, draft, review and dispatch became the spine everything else hangs off.

Three hosts, one agent

The work is split across three machines so a weak orchestration box never blocks the GPU, and the GPU box never has to hold state. A bot host takes the request and dispatches the agent; the agent host runs the agent runtime and the media tooling; and a GPU rig serves the actual models. The hosts talk to each other only over locked-down, token-authenticated internal channels, never anything public-facing.

Task Studio UI Discord Matrix Nostr Bot host Docker host poller + dispatcher Task Studio web UI Eva chat hub private tunnel token auth Agent host no GPU agent runtime media CLIs private link GPU host “Athena” dual-GPU rig llama-server ComfyUI ×2 TTS-WebUI LLM · image · video speech · 3D
Bot host
Orchestration

The Docker box in the diagram at the top of this page. Runs the task poller, the dispatcher, the Task Studio web UI, and the Eva chat hub. Holds no GPU and no models, just state and routing.

Agent host
The agent + tooling

Runs the agent runtime in a fresh workspace per job, plus the whole media toolbox as CLIs. Reachable only over a locked-down, token-authenticated internal channel, never exposed publicly.

GPU host · “Athena”
The models

A dual-GPU rig serving a local LLM via llama-server, ComfyUI for diffusion (a second worker on the other GPU for parallel video), and TTS-WebUI for voices. Services free and reload each other's VRAM on demand.

A local media pipeline the agent drives

The agent doesn't just write text. It can call a full production toolbox, review its own output (a vision model describes each render so the agent can judge it), and composite the pieces together. All of it local, much of it able to fan out across both GPUs:

images · ComfyUI long-form video · narrated + scored + captioned dual-GPU parallel render image → 3D textured .glb text-to-speech · voice clone lip-sync talking-head music + SFX vision-describe (self-review) transcribe + diarize translate · SeamlessM4T upscale + enhance background removal RAG · Qdrant logo compositing protein folding · Boltz-2

Eva: one assistant, every platform

The same brain is reachable as Eva, a chat assistant that lives on Discord, Matrix and Nostr at once through a microservice hub: platform-specific bots forward commands to a central service (with accounts, permissions and bans) that answers from the local model and can queue Task Studio jobs, pinging you back when the work finishes.

Several machines' worth of hardware

None of this is rented. The bot host, the agent host and the GPU rig are physical machines on the server VLAN that I built and keep running myself. That means NVIDIA driver and CUDA upkeep, budgeting VRAM so the LLM, diffusion and speech services can share two cards without evicting each other at the wrong moment, hundreds of gigabytes of model storage, and the fans, power supplies and cabling underneath it all. When a card overheats or a disk starts failing, there is no cloud console to click. The fix is a screwdriver and an afternoon.

Rebuildable on purpose

All three hosts are captured as Ansible. If hardware dies, the reproducible parts (the bot stack, the agent runtime, every media CLI, the model manifest) come back with a command, and the hand-built GPU rig has an honest runbook rather than a fantasy one-click. Model swaps are a deliberate, documented playbook, not a scramble. It's a research toy in scope and a production system in discipline.

The stack

Boring on purpose: everything here is standard, reproducible, and something I'd be comfortable handing to a client.

Debian / Ubuntu Docker Compose OPNsense VLAN segmentation WireGuard Nginx / reverse proxy Let's Encrypt TLS GitLab Nextcloud Jellyfin Mastodon Matrix Nostr Prometheus / Grafana Matomo Ansible Node.js · Rust MongoDB · Qdrant llama.cpp / oobabooga local LLM ComfyUI TTS-WebUI CUDA · dual-GPU TrueNAS · ZFS Automated backups Pi-hole / AdGuard

Mail is the one thing I don't run here. It's handled by a managed provider, because deliverability is a full-time job I'd rather outsource. Everything else, from the metal to the reverse proxy, is mine. Curious about the setup, or want something like it built? Get in touch.