VM Go Brrrr: A Homelab Disaster Story
How I solved the OAuth token complexity problem with a dead-simple persistent VM approach using Packer and Vagrant
The Problem: OAuth Token Hell
When you're trying to automate Claude Code in isolated environments, you hit this fucking annoying wall: OAuth tokens. Every time you destroy and recreate a VM, you need to re-authenticate Claude Code through a browser. This becomes a nightmare when you're trying to run automated development workflows.
Traditional approaches fail because OAuth requires human intervention. You can't script browser authentication flows without getting into security hell.
I bought this little beast to run my homelab - a Minisforum UN100 with an Intel N100 processor, 16GB RAM, and dual gigabit ethernet ports. Small as fuck but handles everything I throw at it.
The specs are solid for a homelab starter:
- Intel N100 Processor (4 cores, up to 3.4 GHz)
- 16GB LPDDR5 RAM
- Dual gigabit ethernet (perfect for network testing)
- Multiple HDMI outputs
- Runs at 7.7W idle, 23.5W under load
The Solution: Persistent VM Pattern
Instead of fighting OAuth complexity, I decided to solve it with infrastructure. The approach is simple: authenticate once, then never destroy the VM.
Implementation Details
The workflow splits into two distinct phases:
Phase 1: Image Creation (Packer)
# Build the authenticated base image
packer build claude-dev.pkr.hcl
# This creates a VirtualBox image with:
# - Ubuntu 20.04 base system
# - Claude Code installed and authenticated
# - Development tools pre-configured
# - Authentication token stored securely
Phase 2: Project Management (Vagrant)
# Daily usage is simple
vagrant up # Boots from authenticated image
vagrant ssh # Jump into development environment
# ... do development work ...
vagrant suspend # Saves state, releases resources
Network Setup with Tailscale
Since I'm running this on my homelab, I use Tailscale for secure remote access and Cloudflare for public applications. The VM gets a static IP on the Tailscale network, making it accessible from anywhere.
# On the VM
sudo tailscale up --ssh
# Now accessible from any device on my Tailscale network
Learning Through Automation
This is my first real homelab setup, and I'm learning the ins and outs of computing as I go. Having Claude Code as an operator makes the learning curve manageable. I can give different Claude instances in different directories their own responsibilities and roles:
/workspace/foreman/
- VM orchestration and monitoring/workspace/projects/
- Active development work/workspace/templates/
- Project templates and scaffolding
Each directory gets its own CLAUDE.md
file with specific instructions and context.
The Results
This pattern eliminated OAuth complexity entirely. Instead of fighting authentication flows, I authenticate once during image creation and never deal with it again. The VM suspend/resume cycle takes seconds instead of minutes for full reprovisioning.
For a homelab setup, this approach scales well. I can create multiple authenticated images for different purposes - one for web development, another for systems work, etc. Each image is self-contained and ready to work.
Implementation Notes
Key decisions that made this work:
- Packer for image creation - Handles the complex OAuth flow once
- Vagrant for project management - Simple, predictable VM lifecycle
- Suspend instead of destroy - Preserves authentication state
- Static networking - Consistent access patterns
- File-based communication - Simple coordination between host and VM
The Minisforum UN100 handles this workload without breaking a sweat. Power consumption stays low, and the dual ethernet ports let me experiment with network configurations.
This pattern works because it separates concerns properly: Packer handles the hard infrastructure problems, Vagrant handles the simple project management, and the persistent authentication state eliminates the OAuth headache entirely.
❤️ Willy out.