DevOps & Homelab Adventures

Welcome! I document my journey learning DevOps, building homelabs, and automating everything.

  • Journal: Weekly learning logs from my DevOps journey
  • Projects: Deep dives into homelab builds and AD labs
  • Docs: Runbooks and reference guides
  • Reading: What I’m learning from books and courses

Subscribe via RSS to follow along.

Chasing a FireWire Ghost: Getting a Nikon Scanner Onto a Proxmox Cluster

I wanted to get an old Nikon Coolscan 8000 film scanner talking to my Proxmox cluster. The scanner is FireWire 800 only, so the plan was an Apple USB-C to Thunderbolt 2 adapter chained into a Thunderbolt to FireWire 800 adapter, both official Apple parts. Simple enough on paper. It took an entire evening and a trip through a motherboard manual to figure out why nothing was showing up. Step One: Which Host Even Has Thunderbolt The cluster is three nodes, pve01 through pve03, all Ryzen 9 5900X boxes. Before chasing the adapter I checked lsusb on all three: ...

August 13, 2026 · 6 min · Adam Behn

BadBox in the Living Room: Forensic Analysis of a VSeeBox V3 Plus

A VSeeBox V3 Plus had been sitting on a quarantine VLAN in my living room since last year. I’d isolated it after suspecting a BadBox infection and hadn’t gotten around to pulling it apart. This weekend I finally did. The short version: the device is infected with BadBox 2.0 malware. The SOCKS5 proxy was live and accepting connections from residential IPs. The DNS blocklist was being bypassed with encrypted DNS. And one domain in the traffic trace points directly back to VSeeBox’s own infrastructure. ...

July 6, 2026 · 6 min · Adam Behn

Why My Shed Lost WiFi: A UISP Agent Eating 100% CPU on a NanoStation

My shed AP had been intermittently dropping off the Unifi controller for weeks. It surfaced during a controller migration when push notifications started firing: “device disconnected for 21 minutes, reconnected.” The other AP and switches were fine. Just the shed. The Setup The shed is about 0.1 miles from the house. A pair of NanoStation Loco M2 devices form a point-to-point wireless bridge between the two buildings. A UAP-AC-Lite hangs off the shed-side bridge to provide WiFi coverage out there. ...

April 21, 2026 · 3 min · Adam Behn

IP Registration Lessons: IPv6, TTL Auto-Renewal, and SSO That Wasn't Worth It

After deploying the self-service IP registration system for family Jellyfin access, three things came up within the first day of real-world testing. IPv6 Privacy Extensions Break Registration The first family member to register got an IPv6 address. The Worker stored it with a /128 (exact match), but when she visited media.8devops.com, her phone used a different IPv6 address. IPv6 privacy extensions rotate the interface identifier (the last 64 bits) on every connection to prevent tracking. ...

April 20, 2026 · 3 min · Adam Behn

Self-Service IP Registration for Family Jellyfin Access

After setting up Cloudflare Tunnel with Zero Trust Access for Jellyfin, I hit a new problem: family members with Rokus and Apple TVs outside my network couldn’t get through the email OTP gate. Streaming device apps can’t render a Cloudflare login page or enter an OTP code. The Problem Cloudflare Access works great for browsers. But Jellyfin client apps on Rokus, Apple TVs, and phones make direct API calls. They need to reach Jellyfin without a browser-based auth step in the middle. ...

April 19, 2026 · 4 min · Adam Behn

Exposing Jellyfin Through Cloudflare Tunnel with Zero Trust Access

I needed to access my Jellyfin media server from a managed work laptop where I can’t install Tailscale or any VPN client. Cloudflare Tunnel solved this: outbound-only connection from the LXC, no open firewall ports, and a Zero Trust email OTP gate before anyone can reach Jellyfin. The Problem My Jellyfin instance runs in an LXC container on Proxmox. It’s accessible over Tailscale from my personal devices, but some environments have endpoint protection that blocks VPN installs. I needed a way to access my media library over plain HTTPS without installing anything on the client. ...

April 18, 2026 · 4 min · Adam Behn

Retiring pve005: Decommissioning a Proxmox Node the Hard Way

Why Now pve005 was an i5-7500 with 16GB of RAM. It ran the original Jellyfin LXC with 1.1TB of media on a local ZFS pool. Once I rebuilt the lab around a 3-node Ryzen 9 cluster with Ceph storage, pve005 became dead weight. The media was migrated to jellyfin01 on the new cluster months ago. The old LXC was stopped. pve005 was still drawing power, still in the Ceph quorum, and still showing up in every Ansible run. ...

April 8, 2026 · 4 min · Adam Behn

Moving a Raspberry Pi Offsite: Everything That Went Wrong

The Plan Move pi-burg, my Raspberry Pi 3 running restic as an offsite backup target, from my house to my mom’s. Simple, right? It already had Tailscale, so once it was on her wifi it would just appear on the tailnet from wherever. Total estimated time: 15 minutes. Total actual time: ~6 hours. The Stack Raspberry Pi 3 running Raspberry Pi OS Lite 8TB USB drive with an existing restic repository Tailscale for tailnet connectivity (no static IPs, no port forwarding) A long drive to mom’s house What Was Supposed to Happen Configure wifi on the Pi for mom’s network before leaving home Drive to mom’s Plug in power, let Tailscale come up Profit What Actually Happened Chapter 1: Cloud-init Is a Liar The Pi was already provisioned, so I edited /boot/firmware/network-config from my Mac to add mom’s wifi. I even recomputed the WPA PSK hash because the stored one was for a different SSID. Saved, ejected, booted. ...

April 4, 2026 · 6 min · Adam Behn

Self-Hosting OpenMemory MCP on Proxmox with Tailscale

The Goal I wanted a persistent AI memory layer — something that stores context across conversations and tools, accessible from Claude Desktop, Claude Code, and eventually other MCP clients. The official mem0 platform exists, but I wanted to self-host it on my Proxmox cluster for control and privacy. The Stack The deployment runs on mem01 (LXC 3003, pve02) with three Docker containers: Ollama — LLM inference for embeddings (bge-m3) and chat (qwen3:8b) OpenMemory — the MCP server itself, using SQLite for vectors and metadata Open WebUI — optional web interface for testing I started with mem0-mcp-selfhosted (Neo4j + Qdrant + Python SDK) but it crashed repeatedly and had a painful dependency chain. OpenMemory — SQLite for everything, Node.js SDK — just worked. ...

March 31, 2026 · 4 min · Adam Behn

Running 6 Minecraft Servers on Proxmox with Docker-in-LXC

The Goal The kids want Minecraft servers. Not one — six. Survival, Creative, Adventure, Minigames, Hardcore, and a modded Fabric server. I have three Ryzen 9 5900X Proxmox nodes with 64-128GB RAM each, so hardware isn’t the problem. The question was how to deploy and manage them without it becoming a second job. The Stack After researching management panels (Pterodactyl, Crafty, AMP, MCSManager), I landed on the simplest approach: Docker Compose with the itzg/minecraft-server image. It handles Paper builds, EULA acceptance, Aikar’s JVM flags, RCON, and graceful shutdown — all via environment variables. No panel needed. ...

March 29, 2026 · 4 min · Adam Behn