From Zero To Mini Homelab

Planning

Introduction

Project Goals

This home lab project is designed to be a practical, efficient, and educational** setup for learning, experimenting, and self-hosting services. The key goals include:

Why a Home Lab?

A home lab provides an isolated environment to experiment with enterprise-grade technologies at home.

Requirements

This project must balance several factors to be functional, reliable, and maintainable:

  1. Physical Constraints
    • Must fit within the DeskPi T0 which is a 4U, 10-inch mini rack.
    • Components should be efficiently arranged for airflow and accessibility.
  2. Power Efficiency
    • Preference for low-power devices such as devices which use embedded CPUs such as the Intel N100.
    • Passive cooling where possible to reduce noise and energy waste.
  3. Network Performance
    • 2.5GbE minimum with potential expansion to 10GbE.
    • Consideration of VLAN segmentation for improved security and traffic management.
  4. Aesthetics & Clean Design
    • A well-organized setup with minimal cable clutter
    • Efficient power delivery to avoid multiple bulky adapters.
  5. Scalability & Extensibility
    • Ability to add more storage, network interfaces, or compute power over time.
    • Modular approach to hardware selection.

Another factor is cost.

Software & Services

Rationalizing Bare Metal vs Virtualized Deployments

While it is certainly possible to run everything in a virtualized environment, certain services are better suited for bare metal deployment.

Another consideration is security and isolation. Services run on bare metal are not at risk of virtualization vulnerabilities. A compromised hypervisor could potentially expose VMs.

Software & Services

Service Type Software Options Deployment Method
DNS Sinkhole Pi-hole, AdGuard, Technitium DNS Bare Metal
Router pfSense, OpnSense, RouterOS Bare Metal
NAS TrueNAS (x86), OMV (ARM) Bare Metal
Media Server Jellyfin Virtualized
Cloud Storage Nextcloud, Seafile, FileRun Virtualized
Mobile Backup TBD Virtualized
Password Manager Bitwarden (Vaultwarden) Virtualized
Smart Home Home Assistant, Frigate Virtualized
VPN WireGuard Virtualized

Form Factor

Mini Rack T0

Other Options

Layout

3D Prints

Devices

Switch

Switch requirements

Options

There are a bunch of affordible options that are simply rebadged.

But unproven.

DNS sinkhole

Router

A ton of options here, but for the rack itself this is not really necessary. From an educational point of view

I will likely introduce a RouterOS device later, but separately from this project. For now, an OpenWRT device running as a repater in the rack is somewhat justifiable on the basis that this allows wireless connectivity to the rack.

OpnSense and pfSense

These run on x86 hardware and while it is true that this opens the door for any hardware, given my constraints on size and power efficiency, this limits the choices to hardware firewall devices.

RouterOS

Not a priority, but the Mikrotik RB50009 is a strong choice.

OpenWRT

Gli.Net

Hypervisor

Device should be

I selected the Minix Z100.

NAS

Low priority, nothing currently meets requrements, however, there are devices which getting there.

TrueNAS requires x86 hardware and does not support ARM. For ARM devices, OMV seems to be the only option. While there are very compelling ARM options, for example (FriendlyElec CM3588), OMV seems lackluster and considerably less mature.

So we’re going x86. First a few points

  1. CPU
Processor Model TDP (Watts) PCI Express Lanes
Intel N100 6 W 9
Intel N125 6 W 9
Intel N355 15 W 9
Core i3-12100T 35 W 20
Core i3-12300T 35 W 20
  1. PCI-Express Lanes

On a typical N100-class board the lanes are deployed as follows

Component PCIe Lanes Used
M.2 NVMe SSD 4 lanes
2.5GbE Network Interface (NIC) 1 lane
Mini PCIe Slot (WiFi, LTE, etc.) 1 lane
SATA Controller (PCIe to SATA) 2 lanes
USB Controller (High-speed USB) 1 lane
Total 9 lanes
  1. PCI Express Bandwidth
PCIe Version Lanes Bandwidth (Gbps) Bandwidth (GBps)
PCIe 3.0 x1 8 Gbps 1 GBps
PCIe 3.0 x4 32 Gbps 4 GBps
PCIe 3.0 x8 64 Gbps 8 GBps
PCIe 3.0 x16 128 Gbps 16 GBps
PCIe 4.0 x1 16 Gbps 2 GBps
PCIe 4.0 x4 64 Gbps 8 GBps
PCIe 4.0 x8 128 Gbps 16 GBps
PCIe 4.0 x16 256 Gbps 32 GBps

Also SATA III has about ~750 MB/s bandwidth.

  1. Network Bandwidth
Ethernet Standard Bandwidth (Gbps) Bandwidth (GBps)
1GbE 1 Gbps 0.125 GBps
2.5GbE 2.5 Gbps 0.3125 GBps
10GbE 10 Gbps 1.25 GBps

So on a 2.5GbE NIC, M2 drives running PCIe 3.0 x1 will be limitted by the network interface.

Running interface bonding/aggregation with two 2.5GbE ports would double the bandwidth, but still be the bottleneck.

  1. Creative Things

A full mini-ITX device

Pros:

Cons:

There are few suitable board options currently.

1-Litre Business PC

SoC NAS Motherboard

But can I trust these devices?

Mini PC

Turnkey Solution

Software Implementation

Ansible

AdGuard Home

https://adguard-dns.io/kb/adguard-home/getting-started/#service https://github.com/AdguardTeam/AdGuardHome?tab=readme-ov-file#guides

Proxmox

Repeater Router

OpenWWRT Repeater in Proxmox

Wi-Fi in Proxmox

The initial network layout in Proxmox is

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vmbr0 state UP group default qlen 1000
    link/ether a0:1e:0b:14:f7:97 brd ff:ff:ff:ff:ff:ff
3: wlo1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 98:5f:41:88:3e:98 brd ff:ff:ff:ff:ff:ff
    altname wlp0s20f3
4: vmbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether a0:1e:0b:14:f7:97 brd ff:ff:ff:ff:ff:ff
    inet 192.168.50.202/24 scope global vmbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::a21e:bff:fe14:f797/64 scope link 
       valid_lft forever preferred_lft forever
5: tap100i0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vmbr0 state UNKNOWN group default qlen 1000
    link/ether 72:87:48:37:36:9c brd ff:ff:ff:ff:ff:ff
6: enx00051b00a05a: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:05:1b:00:a0:5a brd ff:ff:ff:ff:ff:ff

The interfaces, and what they do are:

Interface Type Purpose
lo Loopback Internal system networking (self-referencing interface)
enp1s0 Ethernet Main wired interface, connected to Proxmox bridge vmbr0
wlo1 Wi-Fi Intel AX201 Wi-Fi adapter (initially not connected)
vmbr0 Virtual Bridge Proxmox’s bridge for VM networking, used to connect VMs
tap100i0 TAP Interface Virtual network adapter for a Proxmox VM (ID 100)
enx00051b00a05a USB Ethernet Intended for wired output in OpenWRT, but had issues with bridging

Proxmox’s default network manager is ifupdown and /etc/network/interfaces which is designed to manage wired interfaces. So we need to install a few packages

with

apt install iw wpasupplicant -y

First, we try to bring the interfaces up

ip link set wlo1 up
ip link set enx00051b00a05a up

then, we scan for Wi-Fi networks iw dev wlo1 scan | grep SSID:

SSID: KittenHouseOfMonsters
SSID: McDonald2.0-5G
SSID: 
SSID: 
SSID: McDonald2.0-5G
SSID: KittenHouseOfMonsters
SSID: 
SSID: 

and connect to to KittenHouseOfMonsters with

# Create config file
wpa_passphrase "KittenHouseOfMonsters" "PW" > /etc/wpa_supplicant.conf
# Start connection
wpa_supplicant -B -i wlo1 -c /etc/wpa_supplicant.conf
# Request DHCP IP
dhclient wlo1

Now, when we check ip a s wlo1

3: wlo1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 98:5f:41:88:3e:98 brd ff:ff:ff:ff:ff:ff
    altname wlp0s20f3
    inet 192.168.50.49/24 brd 192.168.50.255 scope global dynamic wlo1
       valid_lft 86363sec preferred_lft 86363sec
    inet6 fe80::9a5f:41ff:fe88:3e98/64 scope link
       valid_lft forever preferred_lft forever

wlo1 is UP and has an IP.

Configure OpenWRT VM

In Proxmox, create VM with ID 101:

qm create 101 --name OpenWRT --memory 512 --net0 virtio,bridge=vmbr0

and download OpenWRT with

cd /var/lib/vz/template/iso
wget https://downloads.openwrt.org/releases/23.05.3/targets/x86/64/openwrt-23.05.3-x86-64-generic-ext4-combined.img.gz
gunzip openwrt-23.05.3-x86-64-generic-ext4-combined.img

Proxmox supports two main types of storage:

The recommended way to store a disk in Proxmox is to convert it to .qcow2 format and place it in local-lvm. I attempted to convert the raw OpenWRT image, but it failed

qemu-img convert -O qcow2 /var/lib/vz/template/iso/openwrt-23.05.3-x86-64-generic-ext4-combined.img /var/lib/vz/template/iso/openwrt.qcow2

and since conversion failed, I used the raw image instead.

By default, Proxmox does not allow VM disk images in local storage. To enable raw image storage, we must edit Proxmox’s storage configuration:

nano /etc/pve/storage.cfg

and modify

dir: local
    path /var/lib/vz
    content iso,backup,template

to

dir: local
    path /var/lib/vz
    content iso,backup,template,images

Then, we move the .raw image

mkdir -p /var/lib/vz/images/101/
mv /var/lib/vz/template/iso/openwrt-23.05.3-x86-64-generic-ext4-combined.img /var/lib/vz/images/101/openwrt.raw

and then we attach the .raw disk as IDE/SATA

qm set 101 --ide0 local:101/openwrt.raw
qm set 101 --boot order=ide0

Network Interface Configuration

Next, we need to configure Proxmox to pass through Wi-Fi (wlo1) and USB Ethernet (enx00051b00a05a) to the VM.

For the USB Ethernet adaptor, this is straight forward. From lsusb the USB Ethernet adapter is identified by

Bus 004 Device 003: ID 0b95:1790 ASIX Electronics Corp. AX88179 Gigabit Ethernet

The vendor ID (0b95) and product ID (1790) identify the device. We use this to pass through the USB Ethernet adapter to OpenWRT.

qm set 101 -usb0 host=0b95:1790

Unlike the USB Ethernet interface, the Wi-Fi interface is connected via PCIe, so we need to enable PCIe passthrough using IOMMU which is enabled in GRUB.

nano /etc/default/grub

and

Querying lspci | grep -i network gives

00:14.3 Network controller: Intel Corporation CNVi: Wi-Fi

so we pass 00:14.3 with

qm set 101 -hostpci0 00:14.3

OpenWRT Configuration

In the OpenWRT VM, check its assigned IP

ip a s

and in my case, OpenWRT is running on an entirely different subnet. So I changed its LAN IP to match my local network

uci set network.lan.ipaddr='192.168.50.2'
uci commit network
/etc/init.d/network restart

Now we can access OpenWRT interface on ‘192.168.50.2’.

Our goal now is to:

Even through the Intel AX201 Wi-Fi card was pased through via PCI passthrough, OpenWRT is not detecting it due to not having drivers for the AX201 chipset.

In Proxmox, download

wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-72.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-73.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-74.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-77.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-79.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-81.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-83.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-84.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-86.ucode
wget https://web.git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/iwlwifi-so-a0-hr-b0-89.ucode

and move them from Proxmox to the lib/firmware directory of the OpenWRT VM. In Proxmox, using scp (secure copy)

scp iwlwifi-so-a0-hr-b0-*.ucode root@192.168.50.2:/lib/firmware/

and in OpenWRT set read permissions for the system to be able to load them

chmod 644 /lib/firmware/iwlwifi-so-a0-hr-b0-*.ucode

then, reload the Intel Wi-Fi driver

rmmod iwlwifi
modprobe iwlwifi
dmesg | grep iwlwifi

However, this still did not work.

Summary

Ultimatley, I could not get this to work. And even if I could, having OpenWRT run in Proxmox in order to act as a repeater is probably not the best idea.

Next, I try to set up a Wi-Fi bridge in Proxmox.

Wi-Fi Bridge In Proxmox

First, undoing the previous steps

In Proxmox, with Wi-Fi connected and the USB Ethernet adapter running.

Assign static IP to the USB Ethernet interface

ip link set enx00051b00a05a up
ip addr add 192.168.50.250/24 dev enx00051b00a05a

Create bridge br0

ip link add br0 type bridge
ip link set br0 up

Add both adapters to the bridge

ip link set enx00051b00a05a master br0
ip link set wlo1 master br0

But this doesn’t work because Wi-Fi doesn’t support Layer 2 bridging (MAC address level).

So isntead, we try NAT forwarding.

Enable IP forwarding

And set up NAT forwarding from USB Ethernet to Wi-Fi

iptables -t nat -A POSTROUTING -o wlo1 -j MASQUERADE
iptables -A FORWARD -i enx00051b00a05a -o wlo1 -j ACCEPT
iptables -A FORWARD -i wlo1 -o enx00051b00a05a -m state --state RELATED,ESTABLISHED -j ACCEPT

This masquerades (NATs) traffic from enx00051b00a05a through wlo1, allowing devices on USB Ethernet to access the internet via Wi-Fi.

Since the USB Ethernet adapter is used for a wired output for the network, we need a DHCP server.

apt install dnsmasq -y

and edit the configuration file

Summary

Bridging failed because

NAT forwarding should have worked, but this needs further investigation.

NGNIX

https://nginxproxymanager.com/

https://pve.proxmox.com/wiki/Web_Interface_Via_Nginx_Proxy

rm /etc/nginx/sites-enabled/default

Home Assistant

https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835

bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/vm/haos-vm.sh)"

Frigate

https://www.restack.io/p/frigate-answer-proxmox-setup-cat-ai

Hardware Implementation

Switch (Mikrotik CSS610-8G-2S+IN)

Power

The CSS610-8G-2S+IN switch can be powered via:

  1. PoE through Ethernet Port #1
  2. 5.5×2.1mm barrel jack (12-57V DC input)

To improve wire management and make the power connection more secure, I plan to relocate the barrel jack. This can be done by either:

Power Input Considerations

Since this setup introduces an additional power input, only one power source should be used at a time to avoid issues with current sharing and backfeed.

The existing barrel jack is located at J1:

Identifying Alternative Power Pads

To find suitable power input points, I used:

The following headers are candidate power points:

Ground Connections

Positive Voltage Connections

PCB Insights

The board has additional headers and features not present in this model but provides useful clues:

Both J13 and J14 connect to J1 via a power trace, but some components are unpopulated. Notably, D48 appears to be designated for a diode, likely intended for power isolation. This suggests the board was designed to support multiple power inputs but may lack isolation components in this model.

Since identifying missing components is difficult without a reference board (e.g., the PoE version CSS610-8P-2S+IN I will assume no built-in power isolation exists. This means care should be taken to avoid using multiple power sources at the same time. A simple solution would be to cover the unused jack when not in use.

Implementation Plan

I will proceed with using the J14 header for power input:

The header pinholes measure 1.7mm and are spaced 5mm apart, so I need to determine a way to securely connect a new power jack without modifying the PCB. Possible solutions:

Mounting

Ears: https://makerworld.com/en/models/1190849-mikrotik-10-inch-mini-rack-ears-rmk-2-10-alternati#profileId-1202558

Hypervisor (Minix Z100)

The PC is powered with a 5.5x2.1mm barrel jack (12V-19V DC).

Beryl AX

Internal antenna on back of case goes to J15