djuntgen@juntgen.com
← all posts
0

Building a Homelab with AI: The Complete Series


What This Is

This is the story of how I took a homelab held together by tribal knowledge and muscle memory and turned it into a fully codified, version-controlled, reproducible infrastructure — pair-programmed with an AI.

I have been a software engineer and Linux administrator for 26 years. I run a homelab on Proxmox with a fleet of LXC containers and VMs: a Docker host, a reverse proxy, a database server, home automation, network monitoring, and more. For years, every service was configured by hand. If a disk failed or a container needed rebuilding, I was piecing things together from memory and terminal scrollback.

This series documents the journey from that state to Infrastructure as Code: Ansible managing every host, Docker Compose stacks auto-deploying via GitOps, a reverse proxy isolated in a DMZ, and security hardening across the board. Every line of code, every playbook, every configuration was built in conversation with Claude Code, Anthropic’s AI CLI tool.

Who This Is For

  • Homelab operators who want to level up from manual configuration to Infrastructure as Code
  • Linux administrators who want a practical security hardening reference
  • Engineers curious about AI-assisted workflows who want to see real examples, not toy demos
  • Anyone running self-hosted services who has ever asked “what happens when this disk fails?”

You should be comfortable with the Linux command line, SSH, and basic networking. I do not explain what a container is or how to use apt. But I do explain Ansible variable precedence, sudoers file naming rules, and why your reverse proxy should not live on the same subnet as your Docker host.

The Series

The AI Toolkit

#PostDescription
1Claude Code: How an AI Pair Programmer Made Me a Super Full Stack EngineerWhat becomes possible when you pair deep domain expertise with the latest LLMs. Prompt engineering, real workflow examples, best practices, and anti-patterns for AI-assisted infrastructure work.

Infrastructure as Code

#PostDescription
2Why Infrastructure as Code? From Manual Configs to Git-Driven HomelabThe motivation for codifying a homelab. Repo structure design, tooling choices (Ansible, Docker Compose, Portainer GitOps), and why IaC is about documentation as much as automation.
3Ansible from Scratch: Bootstrapping a Fleet of LXC ContainersGetting Ansible talking to every host. The chicken-and-egg bootstrap problem, three failed approaches, and the pct exec breakthrough.
4GitOps for Docker Stacks with PortainerAuto-deploying Docker Compose stacks from Git. Portainer configuration, the self-management paradox, and the Portainer API.
5Moving Caddy to the DMZ: Isolating Your Reverse ProxyThe single biggest security improvement in the project. VM vs LXC, Alpine vs Ubuntu, Docker vs bare binary, and Ansible Vault for secrets.
6Security Review: Hardening a Homelab IaC RepoA full security audit of everything we built. Real findings, false positives, defense-in-depth analysis, and the architectural security win.
7Lessons Learned: AI-Assisted Infrastructure as CodeWhat worked, what required course correction, and broader lessons about AI-assisted infrastructure work.

Linux Security Hardening

#PostDescription
8Sudoers Demystified: Understanding Privilege EscalationHow sudo actually works, anatomy of sudoers rules, the NOPASSWD debate, file hierarchy, permissions, and the visudo imperative.
9Linux File Permissions Deep Dive: The Bits That Protect Your HomelabThe permission model, octal notation, ownership, directory permissions, special bits (setuid/setgid/sticky), Docker permission gotchas, and umask.
10Automating Sudoers with Ansible: Never Manually Edit Sudoers AgainBuilding a reusable Ansible role for sudoers management. Bootstrap via Proxmox, visudo validation, permission enforcement, and safe testing workflows.
11Anti-Patterns and War Stories: Sudoers Mistakes That Break Things at 3 AMTen anti-patterns collected from 26 years of Linux administration. The hardening checklist. Why your homelab security matters.

Developer Experience & Tooling

#PostDescription
12Sites, DNS, and MOTDs: A Productive Homelab SessionPlanning a multi-site web architecture, registering a domain, cleaning up DNS, rotating Cloudflare tokens to least privilege, and deploying a dynamic MOTD across the fleet.
13Persistent Terminal Sessions on the Control Node with ZellijInstalling Zellij for persistent SSH sessions. Session serialization, SSH auto-attach via .bashrc, the login vs non-login shell PATH trap, and Nerd Fonts for iTerm2.

AI Agent Infrastructure

#PostDescription
14OpenClaw on Dedicated VM: IaC-First AI Agent DeploymentDeploying an AI agent framework on a dedicated Proxmox VM. Why not Docker-on-docker-host, the Ansible role design, sandbox containers, Day-0 UFW hardening, and SSH tunnel access.
15OpenClaw Day Two: Chasing Ghosts, Trusting the Tunnel, and Closing Security DebtDebugging a Cloudflare ACME 403 and finding the wrong Caddy. The cost of stale documentation in AI-assisted infrastructure work. OpenClaw daemon instability, a deliberate revert, and closing out plaintext secrets in Ansible Vault.
16Cleanup Day: Revoking Dead Tokens, Fixing the Vault, and Learning to Ask Before You BuildRemoving a ghost Caddy container with a hardcoded token, auditing and rotating Cloudflare credentials, simplifying Ansible Vault from double to single encryption, and learning that rsync + docker compose beats GitHub Actions + GHCR + Watchtower for a homelab deploy.
17OpenClaw Round Two: LAN Deployment, Linger Lessons, and Caddy IntegrationPromoting OpenClaw from SSH-tunnel-only to a proper LAN reverse proxy behind Caddy. Four bugs hit and fixed: systemd linger, daemon status triggering restarts, gateway bind mode, and allowedOrigins WebSocket rejection.
18Ansible Best Practices: Six Things We Fixed Before They Became ProblemsA best practices review of the full Ansible codebase. Vault variable indirection, idempotency fixes, SSH AllowUsers, role defaults, removing hardcoded vars, and adding a site.yml master playbook.

Backup and Resilience

#PostDescription
19Phase 3: Backups with Proxmox Backup Server and Google DriveBuilding a 3-2-1 backup chain: PBS LXC provisioned via Terraform, configured via Ansible, nightly PVE backup jobs, and weekly rclone offsite sync to Google Drive. Five gotchas documented: enterprise repo trap, NTS in LXC, OAuth token format, keep-last minimum, and ACL prerequisites.
20Consistent Time Sync Across All Proxmox Hosts with ChronyDiagnosing broken time sync on fresh LXC containers — root cause: Ubuntu/Debian defaulting to NTS (TCP 4460), which fails in Proxmox LXC network namespaces. Fixing it fleet-wide with a two-task Ansible approach and a plain NTP pool template.

Monitoring and Observability

#PostDescription
21Phase 2: Monitoring and Observability with VictoriaMetrics, Grafana, and LokiFull observability for every host: node_exporter via Ansible, VictoriaMetrics + Grafana + Loki + cAdvisor + Alertmanager as a Docker stack, file_sd dynamic target discovery from the Ansible inventory, seven alert rules including a dead man’s switch, and a lesson in how Portainer GitOps actually handles new stacks.
22Security Audit: Scrubbing Usernames and Secrets from a Public Git RepositoryA systematic audit of what was leaking from a public homelab repo: usernames hardcoded in 18 blog posts, Ansible task files, inventory, and API examples. How we moved admin_user to Ansible Vault, parameterised the openclaw role, used sed for bulk doc cleanup, and renamed the agent file.

Reading Order

The series is designed to be read in order, but each post stands on its own. If you are here for a specific topic:

  • Just want to learn about AI-assisted engineering? Start with Post 1.
  • Want to set up IaC for your homelab? Start with Post 2 and read through Post 7.
  • Here for Linux security hardening? Start with Post 8 and read through Post 11.
  • Want the full journey? Start at Post 1 and read straight through.

The Tech Stack

For reference, here is what the homelab looks like:

  • Hypervisor: Proxmox VE on a dedicated host
  • Docker Host: Ubuntu 24.04 LXC (docker-host), running stacks via Portainer
  • Reverse Proxy: Caddy on a dedicated Ubuntu VM in the DMZ, with Cloudflare DNS-01 ACME
  • Configuration Management: Ansible, running from an Ubuntu 24.04 LXC control node (dev)
  • GitOps: Portainer watching a GitHub repo, polling every 5 minutes
  • Secrets: Ansible Vault for IaC secrets, Portainer env vars for runtime secrets
  • DNS: Cloudflare (external), the edge firewall (internal, migration planned)
  • AI Tooling: Claude Code with Claude Opus 4.6

Every Commit Tells a Story

Every AI-assisted commit in the homelab repo includes:

Co-Authored-By: Claude Opus 4.6 <[email protected]>

This is not about giving credit to a machine. It is about transparency. When future-me reads the Git log, I want to know how each change was made. The AI is a tool. The decisions, the architecture, and the accountability are mine.

Let us get started. Post 1: Claude Code awaits.