Setup Runbook¶
Step-by-step guide for deploying the homelab from scratch.
Prerequisites¶
Hardware Ready¶
- [ ] Mini PC with dual NIC
- [ ] Raspberry Pi 5 with SD card
- [ ] Raspberry Pi 4 with 1TB SSD
- [ ] NAS with drives installed
- [ ] MokerLink switch
- [ ] TP-Link PoE switch
- [ ] TP-Link AP
- [ ] Cameras (3x)
- [ ] UPS plugged in and charged
- [ ] All Ethernet cables
Software Ready¶
- [ ] Proxmox VE ISO on USB
- [ ] Debian ISO on USB (Docker VM)
- [ ] Raspberry Pi OS on SD card (RPi 5)
- [ ] Start9 ISO on USB/SD
- [ ] OPNsense ISO downloaded
- [ ] This repo cloned locally
Accounts Ready¶
- [ ] Vultr VPS provisioned
- [ ] Domain (cronova.dev) accessible
- [ ] Cloudflare account configured
- [ ] Google account for backup
Phase 1: VPS Setup (Day 1)¶
Deploy VPS first to enable mesh network for all other devices.
1.1 Provision VPS¶
# SSH into new VPS
ssh root@<vps-ip>
# Update system
apt update && apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com | sh
# Install docker-compose
apt install docker-compose-plugin -y
# Install useful tools
apt install vim git htop -y
1.2 Clone Repo¶
1.3 Deploy Headscale¶
cd /opt/homelab/docker/vps/networking/headscale
# Create .env from example
cp .env.example .env
vim .env # Edit values
# Create config from example
cp config/config.yaml.example config/config.yaml
vim config/config.yaml # Edit domain, etc.
# Start Headscale
docker compose up -d
# Verify
docker compose logs -f
1.4 Configure DNS¶
In Cloudflare, add A record:
hs.cronova.dev→<vps-ip>
1.5 Deploy VPS Caddy¶
1.6 Create First Auth Key¶
# Create user
docker exec headscale headscale users create augusto
# Generate auth key (reusable, no expiry for initial setup)
docker exec headscale headscale preauthkeys create --user augusto --reusable --expiration 24h
# Save this key for connecting devices!
1.7 Deploy Remaining VPS Services¶
# Pi-hole
cd /opt/homelab/docker/vps/networking/pihole
cp .env.example .env
docker compose up -d
# DERP Relay
cd /opt/homelab/docker/vps/networking/derp
cp .env.example .env
docker compose up -d
# Monitoring (Uptime Kuma + ntfy)
cd /opt/homelab/docker/vps/monitoring
cp .env.example .env
docker compose up -d
# Backup
cd /opt/homelab/docker/vps/backup
cp .env.example .env
# Create htpasswd
htpasswd -B -c htpasswd augusto
docker compose up -d
1.8 Verify VPS¶
- [ ] Headscale accessible at https://hs.cronova.dev
- [ ] Pi-hole admin at <http://
:8053 - [ ] Uptime Kuma at <http://
:3001
Phase 2: Network Setup (Day 1-2)¶
2.1 Physical Setup¶
- Connect ISP modem to Mini PC NIC1 (WAN)
- Connect Mini PC NIC2 to MokerLink Port 1
- Connect RPi 5 to MokerLink Port 5
- Connect PoE switch to MokerLink Port 6
- Connect AP to MokerLink Port 7
- Connect NAS to MokerLink Port 4
- Connect RPi 4 to MokerLink Port 3
- Power on all devices
2.2 Install Proxmox VE¶
See docs/guides/proxmox-setup.md for detailed steps.
- Boot Mini PC from Proxmox USB
- Complete installation wizard
- Access web UI at https://192.168.0.237:8006
- Enable IOMMU (optional, for future PCI passthrough)
- Configure network bridges (vmbr0, vmbr1)
2.3 Create OPNsense VM¶
See docs/guides/opnsense-setup.md for detailed steps.
- Upload OPNsense ISO to Proxmox
- Create VM with dual bridged NICs (vmbr0 WAN, vmbr1 LAN)
- Install OPNsense
- Configure WAN (DHCP from ISP)
- Configure LAN (192.168.0.1/24)
- Enable DHCP server
2.4 Configure VLANs¶
See docs/guides/vlan-design.md for detailed steps.
- Create VLANs in OPNsense (10, 20)
- Configure VLAN interfaces
- Set up firewall rules
- Configure MokerLink switch ports
2.5 Join OPNsense to Tailscale¶
# In OPNsense shell
pkg install tailscale
tailscale up --login-server=https://hs.cronova.dev --authkey=<key>
Phase 3: Docker VM (Day 2)¶
3.1 Create Docker VM¶
See docs/guides/proxmox-setup.md for VM creation.
- Create VM (9GB RAM, 100GB disk)
- Install Debian 13 (trixie)
- Configure static IP or DHCP reservation
- Install Docker
3.2 Join Tailscale¶
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --login-server=https://hs.cronova.dev --authkey=<key>
3.3 Clone Repo¶
3.4 Deploy Core Services¶
# Pi-hole (deploy first for DNS)
cd /opt/homelab/docker/fixed/docker-vm/networking/pihole
cp .env.example .env
docker compose up -d
# Update DHCP to use Pi-hole as DNS (192.168.0.10)
# Caddy
cd /opt/homelab/docker/fixed/docker-vm/networking/caddy
cp .env.example .env
docker compose up -d
3.5 Deploy Automation¶
# Mosquitto + Home Assistant
cd /opt/homelab/docker/fixed/docker-vm/automation
cp .env.example .env
docker compose up -d
3.6 Deploy Security¶
# Vaultwarden + Frigate
cd /opt/homelab/docker/fixed/docker-vm/security
cp .env.example .env
# Frigate config
cp frigate.yml.example frigate.yml
vim frigate.yml # Configure cameras
docker compose up -d
3.7 Deploy Media¶
3.8 RPi 5 Setup (OpenClaw)¶
- Flash Raspberry Pi OS to SD card
- Boot RPi 5, configure network (192.168.0.20)
- Connect to MokerLink switch
- Bootstrap with Ansible:
ssh-copy-id augusto@192.168.0.20
ansible-playbook -i inventory.yml playbooks/common.yml -l rpi5 \
-e "ansible_host=192.168.0.20"
ansible-playbook -i inventory.yml playbooks/openclaw.yml -l rpi5 \
-e "ansible_host=192.168.0.20"
ansible-playbook -i inventory.yml playbooks/tailscale.yml -l rpi5 \
-e "ansible_host=192.168.0.20" -e "authkey=tskey-xxx"
Phase 4: NAS Setup (Day 2-3)¶
4.1 Install Debian¶
- Boot NAS from Debian USB
- Minimal install (SSH server only)
- Configure network (static IP or DHCP reservation)
4.2 Mount Drives¶
# Identify drives
lsblk
sudo blkid
# Create mount points
sudo mkdir -p /mnt/{purple,data,external}
# Format if needed (CAUTION: destroys data)
# sudo mkfs.ext4 /dev/sdX
# Add to fstab
sudo vim /etc/fstab
# UUID=xxx /mnt/purple ext4 defaults,noatime 0 2
# UUID=xxx /mnt/data ext4 defaults,noatime 0 2
# Mount
sudo mount -a
# Create directories
sudo mkdir -p /mnt/data/{media,backups,family,photos}
sudo mkdir -p /mnt/purple/frigate
sudo chown -R $USER:$USER /mnt/{purple,data}
4.3 Join Tailscale¶
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --login-server=https://hs.cronova.dev --authkey=<key>
4.4 Configure NFS¶
See docs/guides/nfs-setup.md for detailed steps.
# Install NFS server
sudo apt install nfs-kernel-server
# Export Frigate directory
sudo vim /etc/exports
# /mnt/purple/frigate 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash)
sudo exportfs -ra
4.5 Deploy NAS Services¶
cd /opt
git clone https://github.com/ajhermosilla/homelab.git
cd homelab
# Storage (Samba + Syncthing)
cd docker/fixed/nas/storage
cp .env.example .env
docker compose up -d
# Backup (Restic REST)
cd ../backup
cp .env.example .env
htpasswd -B -c htpasswd augusto
docker compose up -d
4.6 Mount NFS on Docker VM¶
# On Docker VM
sudo apt install nfs-common
sudo mkdir -p /mnt/frigate
sudo mount -t nfs 192.168.0.12:/mnt/purple/frigate /mnt/frigate
# Add to fstab
echo "192.168.0.12:/mnt/purple/frigate /mnt/frigate nfs defaults 0 0" | sudo tee -a /etc/fstab
Phase 5: Start9 Setup (Day 3)¶
5.1 Flash Start9¶
- Download Start9 image
- Flash to SD card or SSD
- Boot RPi 4
5.2 Initial Setup¶
- Access Start9 web interface
- Create admin account
- Configure network
5.3 Install Services¶
- Bitcoin Core (will take days to sync)
- LND
- Electrum Server (after Bitcoin syncs)
5.4 Join Tailscale¶
Install Tailscale via Start9 marketplace or manually.
Phase 6: Camera Setup (Day 3)¶
6.1 Physical Installation¶
- Mount cameras
- Connect PoE cameras to PoE switch
- Power on
6.2 Configure Cameras¶
- Access camera web UI (find IP via DHCP leases)
- Set static IP in IoT range (192.168.10.101-103)
- Configure RTSP streams
- Set passwords
6.3 Add to Frigate¶
Edit frigate.yml with camera details:
Restart Frigate:
6.4 Verify Recordings¶
- Access Frigate at http://192.168.0.10:5000
- Verify cameras show video
- Check recordings in /mnt/frigate
Phase 7: Finalization (Day 3-4)¶
7.1 Configure Backups¶
# On Docker VM - install restic
apt install restic
# Initialize repository
export RESTIC_REPOSITORY="rest:http://$RESTIC_USER:$RESTIC_HTPASSWD@192.168.0.12:8000/homelab"
# Set your restic encryption password
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic init
# Test backup
restic backup /var/lib/headscale --tag headscale
7.2 Set Up Cron Jobs¶
# Edit crontab
crontab -e
# Hourly Headscale backup
0 * * * * /opt/homelab/scripts/backup-headscale.sh
# Daily Vaultwarden backup
0 3 * * * /opt/homelab/scripts/backup-vaultwarden.sh
# Monthly backup verification
0 3 1-7 * 0 /opt/homelab/scripts/backup-verify.sh
7.3 Configure Monitoring¶
- Access Uptime Kuma
- Add monitors (see
docker/vps/monitoring/monitors.md) - Configure ntfy notifications
- Test alerts
7.4 Configure UPS¶
See docs/guides/nut-config.md for NUT setup.
7.5 Final Verification¶
- [ ] All services accessible via Tailscale
- [ ] DNS resolution working (Pi-hole)
- [ ] Media streaming works (Jellyfin)
- [ ] Password manager accessible (Vaultwarden)
- [ ] Cameras recording (Frigate)
- [ ] Backups running
- [ ] Monitoring active
- [ ] UPS graceful shutdown configured
Post-Setup Tasks¶
Week 1¶
- [ ] Wait for Bitcoin sync to complete
- [ ] Configure Home Assistant automations
- [ ] Set up Syncthing folders
- [ ] Import passwords to Vaultwarden
- [ ] Configure media libraries in Jellyfin
Week 2¶
- [ ] Run first backup verification
- [ ] Test restore procedures
- [ ] Configure offsite backup (rclone to Google Drive)
- [ ] Document any customizations
Month 1¶
- [ ] Review monitoring alerts
- [ ] Optimize Frigate detection zones
- [ ] Review firewall rules
- [ ] Update all containers
- [ ] First monthly backup drill
Troubleshooting¶
Can't reach Tailscale devices¶
# Check Tailscale status
tailscale status
# Re-authenticate
tailscale up --login-server=https://hs.cronova.dev --authkey=<key> --force-reauth
Docker containers won't start¶
# Check logs
docker compose logs -f <service>
# Check disk space
df -h
# Check Docker status
systemctl status docker
NFS mount fails¶
# Check NFS server
showmount -e 192.168.0.12
# Check firewall
sudo ufw status
# Test mount manually
sudo mount -v -t nfs 192.168.0.12:/mnt/purple/frigate /mnt/frigate