Setting Up a Homelab from Scratch

Hardware, networking, and a clean Debian install with sensible defaults.

A homelab is any computing environment you control and operate yourself, usually at home. The term covers everything from a single Raspberry Pi running Pi-hole to a rack of servers running a full virtualisation stack. This guide starts at the beginning: choosing hardware, planning your network, installing a base OS, and applying a minimal security posture before you run any services.

1. Hardware selection

The used enterprise desktop market is the best value for a first homelab node. The following machines are well-supported by the Linux kernel, run quietly, and consume modest power:

ModelCPUMax RAMTypical price (used)
Dell OptiPlex 7060/7070Core i5/i7 8th–9th gen64 GB DDR4£80–130
Lenovo ThinkCentre M720qCore i5/i7 8th gen32 GB DDR4£70–110
HP EliteDesk 800 G4 MiniCore i5/i7 8th gen64 GB DDR4£75–120
Fujitsu Esprimo Q958Core i5/i7 8th gen32 GB DDR4£60–100

Avoid first-generation Ryzen desktop chips; some early IOMMU implementations have quirks that complicate GPU passthrough and PCI device assignment. Ryzen 5000 and later are fine.

For storage, start with a 500 GB–1 TB NVMe SSD for the OS and running services, and add spinning drives for bulk data. Consumer HDDs are fine for homelab use; you don’t need enterprise drives unless you care about the vibration tolerance or warranty coverage.

2. Network planning

Before installing anything, sketch your network topology. A minimal but sensible setup separates traffic into at least three VLANs:

A cheap managed switch (TP-Link TL-SG108E, Netgear GS308E) costs around £25 and supports 802.1Q VLANs. Pair it with pfSense or OPNsense on a small box for routing and firewall duties.

3. Installing Debian 12 (Bookworm)

Download the netinst ISO from debian.org, verify the SHA-256 sum, write it to a USB drive:

sha256sum debian-12.5.0-amd64-netinst.iso
# Confirm against the expected hash from the Debian site
dd if=debian-12.5.0-amd64-netinst.iso of=/dev/sdX bs=4M status=progress conv=fsync

During the installer, choose:

After first boot, confirm the disk layout:

lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT
df -h

4. Post-install hardening

4.1 Update and install essentials

apt update && apt full-upgrade -y
apt install -y vim ufw fail2ban git curl wget tmux htop

4.2 SSH key authentication

On your local machine, generate an Ed25519 key if you don’t have one:

ssh-keygen -t ed25519 -C "homelab@$(hostname)" -f ~/.ssh/id_ed25519_homelab

Copy it to the server:

ssh-copy-id -i ~/.ssh/id_ed25519_homelab.pub youruser@192.168.10.5

Then harden /etc/ssh/sshd_config:

PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
AllowUsers youruser
X11Forwarding no
MaxAuthTries 3
systemctl reload sshd

4.3 Firewall with ufw

ufw default deny incoming
ufw default allow outgoing
ufw allow from 192.168.10.0/24 to any port 22 proto tcp
ufw enable
ufw status verbose

Always verify SSH access works from another terminal before closing your current session. Locking yourself out over SSH is a common mistake.

4.4 Automatic security updates

apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

Edit /etc/apt/apt.conf.d/50unattended-upgrades to enable security-only upgrades and optionally configure email notifications.

4.5 Set the hostname and timezone

hostnamectl set-hostname homelab-01
timedatectl set-timezone Europe/London
timedatectl status

5. Static IP configuration

Assign a static IP either via your router’s DHCP reservation (preferred — easier to change later) or directly in /etc/network/interfaces:

auto enp3s0
iface enp3s0 inet static
    address 192.168.20.10/24
    gateway 192.168.20.1
    dns-nameservers 192.168.10.53
systemctl restart networking
ip addr show enp3s0

6. Monitoring baseline

Install a minimal monitoring set before adding services. We use Prometheus node_exporter for metrics and Grafana for dashboards, but a lighter starting point is netdata, which ships with its own web UI:

curl https://get.netdata.cloud/kickstart.sh -o /tmp/netdata-kickstart.sh
# Audit the script before running
bash /tmp/netdata-kickstart.sh --nightly-channel --claim-token YOUR_TOKEN

Bind it to listen only on the management VLAN address to avoid exposing it on all interfaces.

Next steps

With a clean, hardened base OS running: