Homelab
A Proxmox server I built from the ground up to actually understand hypervisors, storage and networking. It now runs 12+ self-hosted services across 11 isolated containers — DNS filtering, photo backup, a password manager, automation, monitoring with phone alerts — reachable from anywhere through Tailscale with zero ports open to the internet and a default-deny firewall in front of everything.
Timeline
Click a stop to open the chapterFirst boot
The main node is an i5-10400F desktop (hostname mohammad-pve) running Proxmox VE 9 — my first real hands-on with a hypervisor instead of just reading about one.
Storage layout
Split the node's disks into two ZFS pools: a fast SSD pool for VM and container state (the "brains" of services), and a striped HDD pool for bulk data like media and files. Some of that storage didn't come from a store — I stripped an SSD and a 2.5" HDD out of an old laptop and installed them straight into the node.
DNS filtering
Started with AdGuard Home as the network's DNS-level ad blocker. It didn't handle parental-control filtering well, so I fully destroyed that container and rebuilt DNS filtering on Pi-hole, reusing the exact same static IP so nothing else on the network needed to change.
Immich + Homepage
Deployed Immich for photo and video backup, plus Homepage as a single dashboard for every service — including a Security Checks panel fed by a script that reports host health and security posture every 5 minutes.
Remote access + HTTPS
Remote access went live through Tailscale instead of a hand-built WireGuard setup: the server is a subnet router, so any of my devices reaches every service by its normal LAN address, with Pi-hole filtering applied remotely too. Caddy became the reverse proxy with friendly .lan names, and Vaultwarden (a self-hosted password manager) gets a real Let's Encrypt certificate through a Cloudflare DNS-01 challenge — with no public DNS record at all.
Hardening + monitoring
Turned on the Proxmox firewall with a default-deny inbound policy and per-container allow-lists, so each app only accepts traffic from the proxy and the dashboard. Uptime Kuma runs 15 uptime checks across the lab (plus Harakeh) and alerts my phone through Telegram; Diun sends a Telegram message when any app has a new release.
Automation + tools
The lab now hosts n8n (which runs my Telegram assistant), an always-on container with Claude Code and Codex that I control from my phone and keep in sync with my PC through Syncthing, a Samba drop share for moving files between devices, and Homebox for tracking what I own and where it's stored.
Second node
The second node — an older laptop — still needs its Proxmox install. Its planned role is a replication target for the main node's data, which matters because photos currently live on a single machine. The router also still isn't pointed at Pi-hole, so filtering covers only devices I've configured by hand or that connect over Tailscale.
Milestones
What broke
From the repo
# fast tier — VM/container state zpool create ssd-pool /dev/sda # bulk tier — striped for capacity, no redundancy zpool create hdd-pool /dev/sdb /dev/sdd zfs set compression=lz4 hdd-pool # cap ARC so it doesn't starve VMs echo "options zfs zfs_arc_max=4294967296" \ > /etc/modprobe.d/zfs.conf