01 Overview
A single-operator, self-hosted platform that turns one laptop-class Ubuntu box into a home cloud: roughly 95 service definitions, about 46 live containers, all defined in code and kept honest by its own monitoring. On top of it sit the things people actually use — media (Immich, Jellyfin, Seafile), Home Assistant, a dental-AI suite, games, and generative-AI apps. The part I'm showing here is the platform underneath them, which I think of as four layers.
Infrastructure
The whole server is written down as a recipe — 7 config files, split by category — so it can be rebuilt from scratch. One “front door” sends each web address to the right service behind it; the same friendly names work whether you're at home or dialing in remotely; the firewall blocks everything by default and opens only what's explicitly allowed; and storage is split across three drives with set roles.
AI gateway
One “brain” that every AI app talks to, fronting ~70 model options. They sit in 20 fallback groups: ask for a model, and if it's busy, rate-limited, or down, the request automatically slides to the next-best one in the group — so an app never just fails. Every call is also recorded end-to-end — a flight recorder for AI requests (what was asked, which model answered, how long it took, what it cost).
Control plane
First-party dashboards: a self-building deploy pipeline, a live vital-signs board for the machine's hardware (CPU, memory, temperature, disk), a log-scan incident responder, a dashboard editor, a file browser, and a web terminal.
Reliability
The server keeps an eye on its own health — a 13-point check every 15 minutes — and texts my phone the moment something looks off. It also backs itself up every night (carefully, so a broken backup can't quietly cause harm), tidies up old files on a schedule, and restarts everything in the right order after a reboot.
02 Why I built it
There was never a single manifesto — the platform grew out of a few concrete wants. I wanted to serve everything from one box and reach it from anywhere without opening a single port to the internet, which is what pushed me toward a Tailscale mesh with split-DNS. I wanted building a new service to be self-service and safe rather than an evening of manual scaffolding, which became the deploy pipeline. And a couple of the layers exist because something broke: a runaway backup once filled the root disk unnoticed for days, so alerting had to reach my phone, and a couple of GPUs double as inference nodes when they're not needed elsewhere, so routing had to know when one was actually in personal use and get out of the way.
03 What I built & how it works
No open ports except a Tailscale funnel; everything behind a reverse proxy on a shared Docker network.
Fig. 1 — traffic enters over Tailscale, resolves through split-DNS and Caddy, and lands on a shared Docker network; cron jobs keep the fleet healthy underneath.
The most involved piece is the deploy pipeline (pipeline-dash): it takes a one-sentence description of a service to build and walks it through eight stages, pausing for me to approve before anything runs and again to review a diff before anything ships.
- Synthesize — repomix packs each directory into a per-repo context bundle (ctx-synthesize) for the agents to work from.
- Research — free-tier web research (Gemini google-search + SearXNG + a reader).
- Plan — a structured implementation plan; home-server-specific keywords route the request to fine-tuned models.
- Validate — an LLM-as-judge scores the plan against five criteria before it proceeds.
- Approve — a human gate; nothing executes until I say so.
- Execute — one of 16 coding-agent executors builds it; a bare-git snapshot taken beforehand is kept as the baseline the review step diffs and reverts against.
- Review — a unified diff with a destructive-change banner on critical files; reject runs
git cleanand reverts everything. - Deploy — a genuinely new service gets a data dir, a firewall rule, a build, and a 90-second health-wait.
04 🛠 Skills & tech used
05 Notable challenges & decisions
Most of the interesting engineering was defensive — keeping automation from quietly breaking the machine it runs on.
Routing that gets out of the way when a GPU's needed elsewhere
Two of the inference GPUs are borrowed from a laptop and a desktop PC that get used for their day jobs. A JuiceGpuGate callback checks a host-side server before routing to a remote node; if that GPU is already busy with something else (util ≥ 60% and the top process isn't Ollama) it raises a rate-limit error so the gateway falls through to the next model. The check lives on the host, not in the LiteLLM container, because the container has no SSH — and every gate is fail-open, so a check-server hiccup never blocks a request.
A backup that quietly filled the root disk
For about ten days in July, a nightly backup wrote to /mnt/usb-drive-1 while the drive was unmounted, so the writes landed on the root filesystem and pinned it at 100% — unnoticed, because alerts only went to a local log on the same disk. Diagnosis came from a df ≫ du divergence pointing at a shadowed mountpoint. The fix added mountpoint-and-writability guards (that log to stderr, not the possibly-missing mount) and moved alerting to ntfy phone push so a silent failure can't happen the same way twice.
Letting an AI deploy without letting it destroy
The execute stage runs coding agents with real reach, so it's wrapped in a bare-git snapshot of the repo taken before anything runs. The review step renders a unified diff, annotates >50% line loss on compose / Caddy / LiteLLM / .env files with a destructive-change banner, and on reject runs git checkout . && git clean -fd to put everything back. A separate registry records deliberately-uninstalled services so automation doesn't resurrect them.
An incident responder that had to survive incidents
system-911 scans every container's logs, fingerprints issues by md5 so duplicates collapse (about 184k rows accumulated), attaches likely-cause hints, and can launch an AI fix agent in an embedded terminal with a live per-session cost counter. Docker-event bursts once stacked concurrent scans and OOM-killed it (exit 134); the fix was a single-flight + trailing-debounce scheduler plus a raised memory ceiling.
The trust model is deliberate — and it's a project of its own. The dashboards run on a LAN-trust assumption and the pipeline holds broad privilege by design (it deploys services and opens ports). That's fine for one operator on a private tailnet; the full security posture — the host/network/container hardening, a multi-service audit, and an in-progress pass that tightens exactly these soft spots — lives on the Network Security & Administration page.
06 Results
Sources: live docker ps, the repo's git history and compose files, LiteLLM config, and the pipeline / monitor databases on the home server (research snapshot, Jul 2026). Some counts are approximate and drift as the fleet changes.
07 Screenshots
No real captures here yet — the dashboards show live keys, host paths, and log data, so they need a secret- and PHI-scrub pass before publishing. Placeholders below describe the intended shots.
waterfall of step cards → streaming logs → the diff review gate
~50 live-health tiles across 6 sections
issue cards + xterm.js AI-fix drawer
telemetry + Tailscale + geo-flagged logins
08 Honest status
This is a live platform I run and depend on daily, which is exactly why it's an architecture showcase rather than something I can hand over as a clone: roughly 95 service definitions, real API keys and host credentials, and my own network wired through the middle. Unlike the smaller projects on this site, there's no de-identified copy to click — the honest version is the writeup and the placeholders above. A couple of caveats I'd rather state plainly: git history stops in early April 2026 even though the platform kept evolving through July (a monitor rewrite, the OOM fix, config touch-ups), so those later changes live as edited files and backups, not commits; and a few older telemetry stacks (Grafana / Prometheus) were retired but still leave stale tiles behind. It's a working system with rough edges, documented rather than hidden.