Post

πŸš€ The Complete Homelab Setup Guide - From Zero to Hero

πŸš€ The Complete Homelab Setup Guide - From Zero to Hero

πŸš€ The Complete Homelab Setup Guide - From Zero to Hero

By Ahmed β€’ September 24, 2024

Complete Homelab Setup

Building a homelab can seem overwhelming at first, but it’s one of the most rewarding tech journeys you can embark on! This comprehensive guide will take you from absolute beginner to running your own cloud infrastructure at home.

🎯 What You’ll Learn

By the end of this guide, you’ll have:

  • A complete understanding of homelab fundamentals
  • A running virtualization environment
  • Multiple self-hosted services
  • Automated deployment and monitoring
  • Network security best practices

πŸ—οΈ Phase 1: Planning Your Homelab

Hardware Requirements

Budget-Friendly Starter Setup ($200-500)

  • Mini PC: Intel NUC or similar (8GB RAM, 256GB SSD)
  • Network: Existing router + Raspberry Pi for Pi-hole
  • Storage: External USB drive for backups

Enthusiast Setup ($500-1500)

  • Server: Dell PowerEdge R720 or HP ProLiant (32GB+ RAM)
  • Network: Managed switch, dedicated firewall
  • Storage: Multiple HDDs in RAID configuration

Professional Setup ($1500+)

  • Multiple Servers: Clustered environment
  • Enterprise Network: VLANs, dedicated firewall
  • Storage: NAS with enterprise drives

Software Stack Planning

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
homelab_stack:
  virtualization:
    options: ["Proxmox VE", "ESXi", "Hyper-V"]
    recommended: "Proxmox VE"
    
  containers:
    options: ["Docker", "Podman", "LXC"]
    recommended: "Docker + Docker Compose"
    
  orchestration:
    options: ["Kubernetes", "Docker Swarm", "Nomad"]
    recommended: "K3s (lightweight Kubernetes)"
    
  monitoring:
    stack: ["Prometheus", "Grafana", "Alert Manager"]
    
  networking:
    firewall: ["pfSense", "OPNsense", "IPFire"]
    vpn: ["WireGuard", "OpenVPN"]

πŸ”§ Phase 2: Core Infrastructure

Step 1: Install Proxmox VE

Proxmox is the perfect hypervisor for homelabs - it’s free, powerful, and enterprise-grade.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Download Proxmox VE ISO from proxmox.com
# Create bootable USB with Rufus (Windows) or dd (Linux)

# After installation, access web interface:
https://your-server-ip:8006

# Initial setup commands:
# Update package lists
apt update && apt upgrade -y

# Configure network bridges
nano /etc/network/interfaces

# Example bridge configuration:
auto vmbr0
iface vmbr0 inet static
    address 192.168.1.10/24
    gateway 192.168.1.1
    bridge-ports eth0
    bridge-stp off
    bridge-fd 0

Step 2: Create Your First VM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Create Ubuntu Server VM template
qm create 9000 --name ubuntu-server-template --memory 2048 --net0 virtio,bridge=vmbr0

# Download Ubuntu Server ISO
cd /var/lib/vz/template/iso
wget https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso

# Attach ISO and configure VM
qm set 9000 --cdrom /var/lib/vz/template/iso/ubuntu-22.04.3-live-server-amd64.iso
qm set 9000 --boot order=scsi0 --scsihw virtio-scsi-pci
qm set 9000 --scsi0 local-lvm:32,iothread=1

# Start VM and install Ubuntu
qm start 9000

🐳 Phase 3: Container Services

Docker Installation and Configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Install Docker on Ubuntu
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# Add user to docker group
sudo usermod -aG docker $USER

# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker --version
docker-compose --version

Essential Services Stack

Create a docker-compose.yml for essential services:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
version: '3.8'

services:
  # Portainer - Docker Management
  portainer:
    container_name: portainer
    image: portainer/portainer-ce:latest
    restart: always
    ports:
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

  # Watchtower - Automatic Updates
  watchtower:
    container_name: watchtower
    image: containrrr/watchtower
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_POLL_INTERVAL=3600

  # Nginx Proxy Manager
  nginx-proxy-manager:
    container_name: npm
    image: jc21/nginx-proxy-manager:latest
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "81:81"
    volumes:
      - npm_data:/data
      - npm_letsencrypt:/etc/letsencrypt

volumes:
  portainer_data:
  npm_data:
  npm_letsencrypt:

Media Server Stack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
version: '3.8'

services:
  # Plex Media Server
  plex:
    container_name: plex
    image: plexinc/pms-docker:latest
    restart: always
    ports:
      - "32400:32400"
    environment:
      - PLEX_CLAIM=${PLEX_CLAIM}
      - PLEX_UID=${PUID}
      - PLEX_GID=${PGID}
    volumes:
      - plex_config:/config
      - ${MEDIA_PATH}:/data/media

  # Sonarr - TV Show Management
  sonarr:
    container_name: sonarr
    image: linuxserver/sonarr:latest
    restart: always
    ports:
      - "8989:8989"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - sonarr_config:/config
      - ${MEDIA_PATH}:/data

  # Radarr - Movie Management  
  radarr:
    container_name: radarr
    image: linuxserver/radarr:latest
    restart: always
    ports:
      - "7878:7878"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - radarr_config:/config
      - ${MEDIA_PATH}:/data

volumes:
  plex_config:
  sonarr_config:
  radarr_config:

πŸ“Š Phase 4: Monitoring and Observability

Prometheus & Grafana Stack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
version: '3.8'

services:
  # Prometheus - Metrics Collection
  prometheus:
    container_name: prometheus
    image: prom/prometheus:latest
    restart: always
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus

  # Grafana - Visualization
  grafana:
    container_name: grafana
    image: grafana/grafana:latest
    restart: always
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin123
    volumes:
      - grafana_data:/var/lib/grafana

  # Node Exporter - System Metrics
  node-exporter:
    container_name: node-exporter
    image: prom/node-exporter:latest
    restart: always
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro

volumes:
  prometheus_data:
  grafana_data:

Sample Prometheus Configuration

Create prometheus.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100']

  - job_name: 'docker-containers'
    static_configs:
      - targets: ['portainer:9000']

πŸ”’ Phase 5: Security and Networking

Pi-hole DNS Setup

1
2
3
4
5
6
7
8
9
10
11
12
# Deploy Pi-hole via Docker
docker run -d \
    --name pihole \
    -p 53:53/tcp -p 53:53/udp \
    -p 8080:80 \
    -e TZ="America/New_York" \
    -e WEBPASSWORD="yourpassword" \
    -v "pihole_config:/etc/pihole" \
    -v "pihole_dnsmasq:/etc/dnsmasq.d" \
    --dns=127.0.0.1 --dns=1.1.1.1 \
    --restart=unless-stopped \
    pihole/pihole:latest

WireGuard VPN Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: '3.8'

services:
  wireguard:
    container_name: wireguard
    image: linuxserver/wireguard:latest
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - SERVERURL=your-domain.com
      - SERVERPORT=51820
      - PEERS=10
    volumes:
      - wireguard_config:/config
      - /lib/modules:/lib/modules
    ports:
      - "51820:51820/udp"
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

volumes:
  wireguard_config:

🏠 Phase 6: Smart Home Integration

Home Assistant Configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
version: '3.8'

services:
  homeassistant:
    container_name: homeassistant
    image: homeassistant/home-assistant:stable
    restart: always
    network_mode: host
    environment:
      - TZ=America/New_York
    volumes:
      - homeassistant_config:/config
      - /etc/localtime:/etc/localtime:ro
    privileged: true

  # MQTT Broker for IoT devices
  mosquitto:
    container_name: mosquitto
    image: eclipse-mosquitto:latest
    restart: always
    ports:
      - "1883:1883"
      - "9001:9001"
    volumes:
      - mosquitto_config:/mosquitto/config
      - mosquitto_data:/mosquitto/data
      - mosquitto_logs:/mosquitto/log

volumes:
  homeassistant_config:
  mosquitto_config:
  mosquitto_data:
  mosquitto_logs:

πŸ”„ Phase 7: Automation and Backup

Automated Backup Script

Create /opt/scripts/backup-homelab.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash

# Homelab Backup Script
BACKUP_DIR="/mnt/backups/$(date +%Y-%m-%d)"
LOG_FILE="/var/log/homelab-backup.log"

# Function to log with timestamp
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Create backup directory
mkdir -p "$BACKUP_DIR"

log "Starting homelab backup..."

# Backup Docker volumes
log "Backing up Docker volumes..."
docker run --rm -v /var/lib/docker/volumes:/source:ro -v "$BACKUP_DIR":/backup alpine tar czf /backup/docker-volumes.tar.gz -C /source .

# Backup Proxmox VMs
log "Backing up Proxmox VMs..."
vzdump --all --compress lzo --storage local --mode snapshot

# Backup configuration files
log "Backing up configuration files..."
tar czf "$BACKUP_DIR/configs.tar.gz" /etc/docker /opt/docker-compose

# Clean old backups (keep 30 days)
find /mnt/backups -name "20*" -type d -mtime +30 -exec rm -rf {} \;

log "Backup completed successfully!"

# Send notification (optional)
curl -X POST "https://hooks.slack.com/your-webhook" \
     -H 'Content-type: application/json' \
     --data '{"text":"Homelab backup completed successfully!"}'

Automated Update Script

Create /opt/scripts/update-homelab.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash

# Automated update script
LOG_FILE="/var/log/homelab-updates.log"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

log "Starting system updates..."

# Update Proxmox host
apt update && apt upgrade -y

# Update Docker containers
cd /opt/docker-compose
docker-compose pull
docker-compose up -d

# Update Kubernetes cluster (if applicable)
if command -v kubectl &> /dev/null; then
    kubectl get nodes
    # Add specific update commands
fi

log "Updates completed!"

πŸŽ“ Advanced Topics

Setting Up Kubernetes (K3s)

1
2
3
4
5
6
7
8
9
10
11
# Install K3s on master node
curl -sfL https://get.k3s.io | sh -

# Get node token for worker nodes
sudo cat /var/lib/rancher/k3s/server/node-token

# Install on worker nodes
curl -sfL https://get.k3s.io | K3S_URL=https://master-ip:6443 K3S_TOKEN=your-token sh -

# Verify cluster
kubectl get nodes

GitOps with ArgoCD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: Namespace
metadata:
  name: argocd
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: homelab-apps
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-username/homelab-k8s
    targetRevision: main
    path: applications
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

🚨 Troubleshooting Common Issues

Docker Container Won’t Start

1
2
3
4
5
6
7
8
9
10
11
# Check container logs
docker logs container-name

# Check resource usage
docker stats

# Restart Docker daemon
sudo systemctl restart docker

# Clean up unused resources
docker system prune -a

Network Connectivity Issues

1
2
3
4
5
6
7
8
9
10
# Test network connectivity
ping 8.8.8.8
nslookup google.com

# Check firewall rules
ufw status
iptables -L

# Verify DNS resolution
dig @1.1.1.1 example.com

Performance Issues

1
2
3
4
5
6
7
8
9
10
# Check system resources
htop
free -h
df -h

# Monitor disk I/O
iotop

# Check network usage
nethogs

πŸ“š Additional Resources

Essential Documentation

Community Resources

YouTube Channels

  • TechnoTim: Excellent homelab tutorials
  • NetworkChuck: Networking and cybersecurity content
  • Craft Computing: Hardware reviews and builds

🎯 What’s Next?

Congratulations on building your homelab! Here are some next steps to consider:

  1. Expand Your Services: Add more self-hosted applications
  2. Improve Monitoring: Set up alerting and advanced dashboards
  3. Enhance Security: Implement network segmentation and intrusion detection
  4. Learn New Technologies: Try container orchestration, infrastructure as code
  5. Share Your Journey: Blog about your experiences and help others!

πŸ’‘ Final Tips

Best Practices

  • Document everything - Future you will thank present you
  • Start small - Don’t try to do everything at once
  • Backup religiously - Test your backups regularly
  • Monitor everything - Know when things break before users do
  • Keep learning - The homelab journey never ends!

Common Mistakes to Avoid

  • Not planning network architecture properly
  • Skipping backups until it’s too late
  • Running everything as root
  • Not monitoring resource usage
  • Forgetting to document configuration changes

Building a homelab is an incredible journey that teaches you real-world skills applicable in any IT environment. Take your time, experiment, and most importantly - have fun! The knowledge you gain from running your own infrastructure is invaluable.

Happy homelabbing! πŸš€


If you found this guide helpful, please star the repository and share it with others in the homelab community! ⭐

This post is licensed under CC BY 4.0 by the author.