minipc-01 · fedora · docker ×14 · ansible ×21
One box.
Everything on it.
Self-hosted services and a local LLM on one mini PC in a closet. The whole machine rebuilds from a single Ansible playbook — 21 roles, from SSH hardening to AI automations that report to Telegram.
The map shows every service by exposure — the further from the core, the closer to the internet. Hover a node or a card below.
Services
15 containers behind one nginx proxy, sorted by how far they are from the internet. Three logins face the world; everything else needs the home network.
public — behind TLS on the open internet
Jellyfin ↗
Media server with AMD VAAPI hardware transcoding. Movies, shows and music, streamed anywhere.
Nextcloud ↗
Personal cloud for files, calendars and contacts, synced from anywhere. MariaDB with Redis caching and a background cron container.
AI chat ↗
Open WebUI talking to the local Ornith 9B model, running on llama.cpp with a 128k context. Gated by Cloudflare Access at the edge — prompts and answers never leave the box.
LAN only — reachable from the home network
Grafana + Prometheus
Metrics and dashboards — CPU and GPU load, CPU and SSD temperatures, disk usage, scraped from node_exporter.
n8n
Workflow automation engine wired to the local LLM. The editor lives on the LAN; Telegram reaches its workflows through a single public webhook path.
Lift document AI
Datalab's 9B vision model, self-hosted. Send a PDF or photo, get schema-constrained data back as a clean PDF.
Pi-hole
Network-wide ad and tracker blocking. DNS sinkhole for every device on the network.
Plex
Second media server for the household. Local streaming to TVs and phones.
NFS
Shared media storage exported over the local network for all machines.
internal — private Docker networks, never published
llama.cpp
Local LLM server running Ornith 9B on the Vega 8 iGPU via Vulkan, with llama-swap handling model loading. Private inference — prompts never leave the box.
Transmission
BitTorrent daemon driven entirely from Telegram — no web UI. Finished downloads land straight in the media library.
MariaDB
Central database behind Nextcloud and future apps. Lives on a private Docker network, never published to the host.
AI automations
n8n workflows call the local Ornith 9B model over a private Docker network. Everything is processed on-device; only the finished summary leaves the box, straight to Telegram.
Morning briefing
Local weather, today's Google Calendar events, top news headlines and server metrics from Prometheus — the LLM composes it all into one good-morning message.
Image update watcher
Checks Docker Hub for every pinned image, compares versions deterministically, and the LLM writes the change notice.
Security report
A systemd timer snapshots SSH auth attempts and fail2ban bans from the journal; the LLM summarizes the week's attack activity.
Document extraction
Send the bot a receipt, invoice or any document photo — a 9B vision model reads it, extracts the fields a caption-selected schema asks for, and replies with a rendered PDF.
Media sorter
Send the bot a magnet link — Transmission downloads it and pings a webhook the moment it finishes; the LLM classifies the release, maps every episode in a season pack, and files it all into the library with clean Plex naming.
Build timeline
-
2026-06-04
git init
Repo born. Base roles: users, SSH hardening, firewalld, Docker, Pi-hole, fail2ban, automatic updates.
-
2026-07-04
Media era
Jellyfin with AMD VAAPI hardware transcoding, Plex, NFS media share — plus nginx reverse proxy and Let's Encrypt DNS-01 certificates.
-
2026-07-05
Eyes and cloud
This website. Uptime Kuma, hardware sensors, Prometheus + Grafana dashboards. Nextcloud on MariaDB with Redis.
-
2026-07-06
AI era
Ollama serving Qwen3 locally, n8n automation engine, and three LLM-powered workflows reporting to Telegram.
-
2026-07-07
Document AI
Datalab lift 9B vision model self-hosted on CPU. A gateway rasterizes PDFs, extracts schema-constrained JSON and renders the result back to PDF — driven from Telegram.
-
2026-07-07
Media pipeline
Transmission wired to Telegram: send a magnet, the LLM classifies the release and files it into the Plex/Jellyfin library. Downloads, sorting and naming, all on-device.
-
2026-07-09
Morning briefing
The daily digest grows up: weather, Google Calendar events and news headlines join the server metrics, composed by the local LLM into one 07:30 Telegram message.
-
2026-07-11
Sharper brain, faster pipeline
All LLM workflows switch to Ornith 9B after a CPU benchmark bake-off. The media sorter goes event-driven — Transmission fires a webhook the second a download completes — and learns to sort whole season packs, episode by episode.
-
2026-07-18
Memory doubled, models tripled
A second RAM stick unlocks dual-channel bandwidth — inference speed nearly doubles overnight. A three-way bake-off crowns Qwen3.6 35B as the new workflow brain, and the lift vision model steps up to a near-lossless quant with double the context.
-
2026-07-18
Chat with the box
Open WebUI puts a face on the local LLM — chat from any browser, anywhere, behind Cloudflare Access. Tuned for CPU inference: a "hello" that first took five minutes now answers in three seconds.
-
2026-07-22
New brain
Ornith 35B takes over from Qwen3.6 as the workflow and chat model. Same tokens per second, but it loads in three quarters of the time and answers straight away instead of thinking out loud first — so replies arrive sooner without the box working any harder.
-
2026-08-13
The iGPU wakes up
Ollama gives way to llama.cpp, and inference moves off the CPU onto the Vega 8 through Vulkan — prompt processing gets five and a half times faster. One model now serves everything, held in memory permanently so it remembers the start of a long conversation instead of re-reading it every turn. Chat, the document reader and every automation share it.
-
2026-08-14
Ornith comes back
The 9B model that ran the workflows back in July returns as the one brain for everything — chat, the coding agent and all five automations. Same size and the same speed as the model it replaces, because underneath they are the same architecture differently tuned; the swap is a bet on how it writes, not on how fast it runs. Roughly eight gigabytes resident, which leaves the long-conversation cache plenty of room. The previous model stays on disk, one line away, in case the new one disappoints.
Spec plate
- hardware
- Mini PC · AMD Ryzen R2544 · 32 GB RAM dual-channel · 512 GB NVMe · iGPU Vega 8
- os
- Fedora Server
- containers
- Docker + Compose
- automation
- Ansible — 22 idempotent roles, secrets in Ansible Vault
- ai
- llama.cpp + llama-swap · Ornith 9B (128k ctx) on Vega 8 via Vulkan · lift 9B vision model · n8n workflows · Open WebUI chat
- ingress
- nginx reverse proxy · TLS via Let's Encrypt DNS-01 (Cloudflare)
- database
- MariaDB 11 · Redis · isolated Docker network
- security
- SSH hardening · firewalld · fail2ban · automatic updates
- monitoring
- Prometheus + Grafana · Uptime Kuma · hardware sensors · Telegram alerts