Proxmox for homelab
When my vCenter and ESXi licenses expired, I needed free alternatives. Hereโs what I found and how to set it up.
vCenter / ESXi Alternatives
1. Proxmox VE (Recommended)
Replaces both ESXi + vCenter in a single install.
| VMware Feature | Proxmox Equivalent |
|---|---|
| ESXi | Proxmox VE (KVM+QEMU) |
| vCenter | Built-in web UI |
| vMotion | Live migration |
| VMFS | LVM / LVM-thin / ZFS |
| Distributed Switch | Linux bridges |
Best for: Homelabs, small clusters
2. XCP-ng + Xen Orchestra
| VMware | XCP-ng Stack |
|---|---|
| ESXi | XCP-ng |
| vCenter | Xen Orchestra |
Best for: VMware-like architecture
3. KVM + libvirt (Minimal)
| VMware | KVM Stack |
|---|---|
| ESXi | KVM (kernel) |
| vCenter | libvirt/virt-manager |
Best for: DIY, automation-heavy
Quick Decision
| Use Case | Choice |
|---|---|
| Homelab | Proxmox |
| VMware-like | XCP-ng |
| Minimal | KVM |
Proxmox Installation
1. Download ISO
From proxmox.com
2. Create Bootable USB (Mac)
sudo dd if=proxmox-ve.iso of=/dev/diskX bs=4M status=progress
Or use Balena Etcher.
3. BIOS Settings
- Disable Secure Boot
- Enable VT-x / VT-d
- Boot mode = UEFI
4. Install Proxmox
Boot from USB โ follow installer:
| Option | Recommendation |
|---|---|
| Disk | Internal SSD |
| Filesystem | ZFS (gives snapshots) |
| IP | Static (important for cluster) |
5. First Login
https://<IP>:8006
user: root
password: (your่ฎพ็ฝฎ็ๅฏ็ )
Configure Updates
Remove Enterprise Repo
sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list
echo "deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list
apt update && apt full-upgrade -y
Remove Subscription Popup
sed -i "s/data.status !== 'Active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
systemctl restart pveproxy
Make Popup Fix Persistent
Create apt hook:
echo 'DPkg::Post-Invoke {
"sed -i \"s/data.status !== '\"'\"Active'\"'\"'/false/g\" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"systemctl restart pveproxy || true";
};' > /etc/apt/apt.conf.d/99proxmox-popup-fix
Option A: iSCSI + LVM
On QNAP / SAN
- Storage & Snapshots โ iSCSI
- Create Target (e.g.,
proxmox-target) - Create Block-based LUN (NOT file-based)
- Attach LUN to target
- Note the Target IQN
On Proxmox
- Datacenter โ Storage โ Add โ iSCSI
- ID:
qnap-iscsi - Portal:
<QNAP-IP> - Target: select discovered IQN
- ID:
- Add โ LVM
- ID:
qnap-lvm - Base storage:
qnap-iscsi - Volume: (your LUN)
- Content: Disk image
- ID:
- (Recommended) Add โ LVM-Thin for snapshots
Option B: NFS
On NAS (QNAP/Synology/TrueNAS)
- Create NFS share
- Allow access from Proxmox IP
- Mount options:
rw,no_root_squash,subdir_check=
On Proxmox
- Datacenter โ Storage โ Add โ NFS
- ID:
qnap-nfs - IP:
<NAS-IP> - Export:
<nfs-share-path> - Content: Disk image, ISO image
- ID:
Quick Comparison
| Storage | When to Use |
|---|---|
| iSCSI + LVM | SAN-style, block access |
| NFS | Simpler, file-based |
| ZFS (local) | Single node, snapshots |
| Ceph | Multi-node HCI |
Cluster Setup (Optional)
1. Prepare Nodes
Set hostname:
hostnamectl set-hostname pve1
Update /etc/hosts on ALL nodes:
192.168.1.10 pve1
192.168.1.11 pve2
192.168.1.12 pve3
Enable passwordless SSH:
ssh-copy-id root@pve2
2. Create Cluster
On pve1:
pvecm create homelab-cluster
On other nodes:
pvecm add 192.168.1.10
Verify:
pvecm nodes
3. Enable HA
- Datacenter โ HA โ Groups โ Create
- Add nodes
- Select VM โ More โ Manage HA
Note: 2-Node Cluster
Set expected votes to avoid quorum issues:
pvecm expected 1
Common Mistakes
- Using file-based LUN instead of block-based
- Running iSCSI over WiFi
- Mixing VM traffic + storage on same NIC
- Not adding LVM layer (iSCSI alone wonโt store VMs)
Next Steps
- Add cloud-init templates for VM provisioning
- Set up backups with Proxmox Backup Server
- Add Ceph for hyperconverged storage (3+ nodes)
Ansible Automation
Inventory
[proxmox_nodes]
pve1 ansible_host=192.168.1.10
pve2 ansible_host=192.168.1.11
pve3 ansible_host=192.168.1.12
[proxmox_nodes:vars]
ansible_user=root
proxmox_ntp_server: "pool.ntp.org"
Playbook: Configure No-Subscription Updates
- name: Configure Proxmox no-subscription repo
hosts: proxmox_nodes
become: true
vars:
proxmox_ntp_server: "pool.ntp.org"
tasks:
- name: Disable enterprise repo
shell: |
sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list
- name: Add no-subscription repo
ansible.builtin.copy:
content: |
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription
dest: /etc/apt/sources.list.d/pve-no-subscription.list
- name: Remove subscription popup
ansible.builtin.replace:
path: /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
regexp: "data.status !== 'Active'"
replace: "false"
- name: Restart web service
ansible.builtin.service:
name: pveproxy
state: restarted
- name: Create apt hook for popup fix
ansible.builtin.copy:
content: |
DPkg::Post-Invoke {
"sed -i \"s/data.status !== 'Active'/false/g\" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"systemctl restart pveproxy || true";
};
dest: /etc/apt/apt.conf.d/99proxmox-popup-fix
- name: Install chrony
ansible.builtin.apt:
name: chrony
state: present
- name: Configure NTP server
ansible.builtin.lineinfile:
path: /etc/chrony/chrony.conf
regexp: "^server"
line: "server iburst"
state: present
- name: Enable and start chrony
ansible.builtin.service:
name: chrony
enabled: yes
state: started
- name: Run apt update
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
- name: Upgrade packages
ansible.builtin.apt:
upgrade: full
Run
ansible-playbook -i inventory.ini proxmox-setup.yml