Proxmox VE is a free, open-source virtualization platform built on Debian Linux that gives you a clean web interface to run virtual machines (KVM) and containers (LXC) on a single box or a whole cluster. It’s the backbone of most serious homelabs, and for good reason: it’s fast, stable, and doesn’t nickel-and-dime you.
This guide takes you from a blank machine to a properly configured node — installing Proxmox, fixing the repositories, reclaiming wasted disk space, enabling IOMMU for passthrough, and wiring up the storage and networking that make a homelab actually useful (ZFS pools, LACP link bonding, and NFS shares from a NAS). The optional sections are marked, so skip whatever doesn’t apply to your hardware.
This Erases the Target DiskThe Proxmox installer wipes the entire drive you select as the install target. Make sure nothing important lives on it, and double-check you’re picking the right disk — especially on a machine with multiple drives.
Requirements
- A computer/server to act as your node — at least 2 GB RAM (4 GB+ recommended), 32 GB+ storage (SSD/NVMe recommended)
- An 8 GB+ USB drive
- A second computer to create the bootable USB
- A stable internet connection
Download the Proxmox VE ISO
Head to the official downloads page and grab the latest Proxmox VE ISO:
TIPIf you want to be thorough, verify the ISO’s checksum after downloading to confirm the file wasn’t corrupted or tampered with. The hashes are listed right next to the download link.
Create a Bootable USB Drive
Use whichever tool you’re comfortable with. Rufus is my go-to on Windows; Balena Etcher works everywhere.
Rufus (Windows)
- Download Rufus from https://rufus.ie/ and launch it as Administrator.
- Insert your USB drive and select it under Device.
- Click SELECT and choose the Proxmox VE ISO.
- Set the partition scheme to GPT.
- Click START and wait for it to finish.
Balena Etcher (Cross-Platform)
- Download Etcher from https://etcher.balena.io/ and launch it.
- Click Flash from file and select the Proxmox VE ISO.
- Click Select target and choose your USB drive.
- Click Flash! and wait for it to complete.
Boot from the USB Drive
- Enter your BIOS/UEFI setup by pressing
F2,F12,Delete, orEscduring boot. The exact key varies by manufacturer — watch the boot screen for the prompt. - Disable Secure Boot if it’s present.
- Set the USB drive as the first boot priority.
- Save and exit. The system should boot into the Proxmox VE installer.
Installing Proxmox VE
-
When the boot screen appears, select Install Proxmox VE and press Enter.
-
Read and accept the End User License Agreement by clicking I agree.
-
Target hard disk: choose your installation drive.
Filesystem ChoiceClick Options here to pick your filesystem. I use EXT4 on a single-drive setup — it’s fast, lightweight, and uses less RAM. If you have multiple drives and want RAID redundancy, data-integrity checks, and snapshots, choose ZFS and set the RAID level (e.g. RAID1/mirror for two drives). Swap size is auto-calculated but can be customized under Options too.
-
Select your country, time zone, and keyboard layout.
-
Create a strong root password (you’ll log in with this), confirm it, and enter a valid email address for system notifications.
-
Management network configuration: the interface is usually auto-detected. Enter a hostname like
pve.local, then choose:- DHCP — automatic IP assignment (easiest for beginners), or
- Static IP — more control. Example values:
- IP Address:
192.168.1.10/24 - Gateway:
192.168.1.1 - DNS Server:
1.1.1.1
- IP Address:
-
Review everything in the installation summary, then click Install.
First Boot and Login
When installation completes, remove the USB drive when prompted and click Reboot so the system starts from the hard drive. On first boot you’ll see Linux boot messages, then a console login prompt showing the node’s IP address.
To reach the web interface, open a browser on another computer on the same network and go to:
https://YOUR-PROXMOX-IP:8006For example: https://192.168.1.10:8006
Accept the self-signed certificate warning, then log in with:
- Username:
root - Password: the one you set during installation
- Realm:
Linux PAM standard authentication
You’ll see a “No valid subscription” notice — that’s completely normal for home use. Click OK to continue. We’ll get rid of that popup in the next section.
Post-Install: Fix the Repositories
A fresh install points at the enterprise repository, which requires a paid subscription and will throw errors on apt update. For a homelab you want the no-subscription repo instead.
The manual way (what’s happening under the hood)
- Go to Node > Repositories and disable the enterprise repositories (
pve-enterpriseandceph-enterprise). - Click Add and enable the No-Subscription repository.
- Go to Updates > Refresh, then click Upgrade to pull the latest packages.
The easy way (recommended)
The community-maintained PVE Post Install script does all of the above plus removes the subscription nag popup, in one shot. Run it in the Node > Shell:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/post-pve-install.sh)"Answer the prompts like this:
- Enterprise / Ceph-Enterprise repos:
disable - No-Subscription repo:
keep(enabled) - Test/beta repo:
no(it’s unstable — skip it) - Subscription nag:
yes(disable it) - Update now:
yes
The High Availability PromptThe script asks whether to disable High Availability (HA) services. If this is a single standalone node, answer yes to reclaim the resources. But if this node is part of a cluster, answer no — you’ll want HA services running as part of the cluster stack. Also remember: run this script on every node in a cluster individually.
After it finishes, reboot the node, then do a hard reload (Ctrl+Shift+R) in your browser before using the web UI to avoid stale cached pages.
Reclaim Space: Delete local-lvm and Resize local
Read This FirstThis assumes a fresh install without ZFS as the root filesystem. It’s only worth doing if you have a small boot drive and need to reclaim space. If you run all your VM/CT disks on that same boot drive, skip this section. If you’re new to LVM, watch this video before touching anything.
By default Proxmox splits the boot drive into local (ISOs, templates, backups) and local-lvm (VM/CT disks). If you store your VMs and containers on a separate storage pool, that local-lvm partition just sits there unused. Here’s how to delete it and give the space back to local.
- Delete local-lvm from the web interface under Datacenter > Storage.
- Open Node > Shell and run:
lvremove /dev/pve/datalvresize -l +100%FREE /dev/pve/rootresize2fs /dev/mapper/pve-rootCheck under Node > Disks > LVM (or df -h) to confirm local is now using the full available space. Reassign storage for your containers and VMs if needed.
Enable IOMMU (for PCI / GPU Passthrough)
If you plan to pass a GPU, NIC, or other PCIe device through to a VM, you need IOMMU enabled — first in the BIOS, then in GRUB.
In the BIOS, the layout differs per manufacturer:
- AMD boards: usually under AMD CBS > NBIO Settings.
- Intel boards: usually VT-d under the CPU options.
In GRUB, open the config from the Node > Shell:
nano /etc/default/grubFind the line GRUB_CMDLINE_LINUX_DEFAULT="quiet" and add intel_iommu=on or amd_iommu=on depending on your chipset:
# Should look like this (Intel example)GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"Update GRUB and reboot:
update-grubAfter the reboot, confirm it’s active:
dmesg | grep -e DMAR -e IOMMUdmesg | grep 'remapping'For the full picture on GPU passthrough and PCI passthrough in general, the official docs are excellent:
(Optional) Create a ZFS Storage Pool
NOTESkip this if you only have one storage device in your PC, mini-PC, or server. This is for adding extra drives with redundancy.
Adding drives as a ZFS pool gives you redundancy (a failed drive won’t take your data with it), compression, and snapshots. Proxmox makes it painless.
-
Go to Node > Disks and confirm all your drives are detected.
-
Wipe every disk you plan to use via Node > Disks > Wipe Disk.
WARNING
Wiping erases everything on the disk. Make sure there’s no important data on it and back up first if you’re unsure.
-
Go to Node > Disks > ZFS > Create: ZFS.
-
Select the drives you want in the pool and pick a RAID level:
- single — one drive (no redundancy)
- mirror — two drives (RAID1-style)
- RAIDZ — three or more drives
-
Enable compression (
lz4orzstdare great defaults). -
Name the pool something like
tank, and check “Add to Storage” so it’s immediately usable for VMs and containers.
(Optional) Bond Two NICs with LACP
NOTESkip this if your node has a single NIC. This bonds two physical ports into one faster, redundant link.
If your node has two network ports and your switch supports 802.3ad (LACP), you can bond them into a single logical link — in my case, two 2.5G ports become one 5 Gbps pipe with automatic failover if a cable dies.
Because the Proxmox GUI validates network changes strictly, the trick is the “drop and catch” method: you queue up the config on the Proxmox side (which drops the connection), then configure the switch to complete the LACP handshake and restore it.
Phase 1 — Proxmox (the “drop”)
- Free the primary interface: go to Node > System > Network, double-click your main bridge (
vmbr0), erasenic0from the Bridge ports field so it’s blank, and click OK. - Create the bond: click Create > Linux Bond and set:
- Name:
bond0 - Slaves:
nic0 nic1(space-separated) - Mode:
LACP (802.3ad) - Hash policy:
layer2+3 - Click Create.
- Name:
- Attach the bond to the bridge: double-click
vmbr0again and set Bridge ports tobond0. Leave the IP and gateway untouched. Click OK. - Click Apply Configuration. The connection will intentionally drop while Proxmox waits for the switch to answer the LACP handshake.
Phase 2 — MikroTik CRS310 (the “catch”)
Using WinBox/WebFig: go to Interfaces > Bonding, add a bond named bond-pve with the two server-facing ports as slaves, mode 802.3ad, and transmit hash layer-2-and-3. Then under Bridge > Ports, remove the individual ports and add bond-pve instead.
The equivalent RouterOS CLI:
/interface bondingadd name=bond-pve slaves=ether1,ether2 mode=802.3ad transmit-hash-policy=layer-2-and-3
/interface bridge portremove [find interface=ether1]remove [find interface=ether2]add bridge=bridge interface=bond-pveThe moment this saves, the switch and Proxmox complete their handshake and the link comes back — now at bonded speed.
The equivalent config file
If you prefer editing directly (or need to reference it), this is what the bond looks like in Proxmox’s network config:
auto bond0iface bond0 inet manual bond-slaves nic0 nic1 bond-miimon 100 bond-mode 802.3ad bond-xmit-hash-policy layer2+3
auto vmbr0iface vmbr0 inet static address 192.168.1.10/24 gateway 192.168.1.1 bridge-ports bond0 bridge-stp off bridge-fd 0Verify it’s working
On the Proxmox node:
cat /proc/net/bonding/bond0ethtool bond0 | grep Speedip -br linkYou’re looking for Bonding Mode: IEEE 802.3ad, MII Status: up, both NICs participating, and — the key detail — a matching Actor Key and Partner Key (that means the switch and server agreed):
Bonding Mode: IEEE 802.3ad Dynamic link aggregationTransmit Hash Policy: layer2+3 (2)MII Status: up Actor Key: 11 Partner Key: 11Slave Interface: nic0 MII Status: up Speed: 2500 MbpsSlave Interface: nic1 MII Status: up Speed: 2500 MbpsAnd the money shot — ethtool confirming the aggregate:
Speed: 5000Mb/sOn the MikroTik side:
/interface bonding monitor bond-pveThis should report active-ports: ether1,ether2.
Have a Physical Fail-SafeIf the LACP handshake fails, you can get locked out of the web GUI. Keep a keyboard and monitor plugged into the node. To recover from the console: log in as
root, runnano /etc/network/interfaces, changebridge-ports bond0back tobridge-ports nic0, save, and reload the network withifreload -ato instantly restore standard single-NIC access.
Mount an NFS Share from a NAS
Pulling storage from a NAS (like a Synology) over NFS is the cleanest way to give your VMs and containers access to bulk storage — media libraries, downloads, backups, whatever. There are two sides: export the folder on the NAS, then add it in Proxmox.
On the Synology (DSM)
Go to Control Panel > Shared Folder, right-click the folder you want to share, choose Edit > NFS Permissions > Create, and set:
- Hostname or IP: your Proxmox host IP (and any container IP that needs direct access)
- Privilege:
Read/Write— required if apps need to write/download/modify (Radarr, Sonarr, Plex, Jellyfin, qBittorrent, etc.) - Squash:
Map all users to admin - Security:
sys - ✅ Enable asynchronous
- ✅ Allow connections from non-privileged ports (ports above 1024)
- ✅ Allow users to access mounted subfolders
Click Save, then Save again on the shared folder dialog. Note the mount path shown — you’ll need it in Proxmox.
On Proxmox
Go to Datacenter > Storage > Add > NFS and fill in:
- ID:
synology-media - Server:
192.168.1.20 - Export:
/volume1/media(this auto-populates in the dropdown once the server is reachable) - Content:
Disk image(or whatever content types you need) - Nodes: All
Once added, the share is mounted on the host at /mnt/pve/synology-media.
Bind the share into a container
To give an LXC direct access to that storage (or a ZFS path), edit the container’s config from the Node > Shell. For example, container ID 100:
nano /etc/pve/lxc/100.confAdd this line at the bottom:
lxc.mount.entry: /mnt/pve/synology-media mnt/media none bind,create=dir 0 0Restart the container, then confirm the mount is visible from inside it:
ls /mnt/mediaUnprivileged Container PermissionsFor unprivileged containers, the classic gotcha is UID/GID mapping — files written by an app inside the container can end up owned by an unexpected user on the NAS. The
Map all users to adminsquash setting above sidesteps most of this. If you hit “permission denied” errors, that mapping is the first place to look.
Conclusion
That’s a homelab-ready Proxmox node: installed, on the right repositories, with wasted space reclaimed, IOMMU ready for passthrough, and proper storage and networking underneath it. From here the fun part begins — spinning up VMs and containers for whatever you want to self-host. Build it, break it, learn from it.
Happy Homelabbing!