SSD Nodes Learn
How to do am Matt ConnorBy Matt Connor · Updated 2026-07-24

can I run Proxmox for VPS?

Check if your VPS support nested virtualization with kvm-ok. If you no see VT-x or AMD-V flags, you no fit run Proxmox or any VM inside your VPS.

The short answer

Nested virtualization na when hypervisor dey run inside virtual machine: your VPS na guest already, and you want make e host guests of its own. E go work only when your provider's hypervisor decide to show CPU virtualization extensions to your instance — check /proc/cpuinfo for the vmx flag (Intel) or svm (AMD), and if you no see any of dem, nothing wey you configure inside VPS go fix am.

One thing wey you must know first: Docker no need any of this. Containers dey share your VPS kernel and dem no dey touch /dev/kvm. If your real goal na "run several services in containers on my server", you don get wetin you need already. Nesting dey important only when you want second kernel — like Proxmox lab, Windows guest, Firecracker microVMs, Android emulator, Kubernetes testbed of real VMs, or CI runners wey dey boot VM images.

Wetin exactly dey inside nesting

Three layers:

  • L0 — the provider hypervisor wey dey on top hardware. You no get access to am.
  • L1 — your VPS. For L0, this one na just guest.
  • L2 — the VM wey you wan run inside your VPS.

Hardware virtualization na VT-x (the vmx flag) plus EPT for Intel, AMD-V / SVM (svm) plus RVI/NPT for AMD. Hypervisor dey use those instructions enter guest mode and make CPU walk two page tables at once.

Dem no design any of dem for re-entrant use, so dem dey emulate nesting: when L1 run VMX instruction, e go trap to L0, wey go manage shadow structures for L2 for L1 side. KVM dey do this well, but L0 dey do extra work every time exit dey happen — na why provider must opt in.

Two conditions must dey hold for accelerated L2:

  1. L0 KVM module must load with nested=1.
  2. L0 must give your VPS CPU model wey get the flag — <cpu mode='host-passthrough'/> for libvirt, cpu: host for Proxmox, -cpu host for raw QEMU. Generic emulated model (qemu64, kvm64) dey hide vmx even when nesting dey on globally.

Check your VPS in one minute

# 1. Are you in a VM, and under what?
systemd-detect-virt          # kvm, vmware, xen, microsoft, or "none" on metal

# 2. Does the CPU expose the extensions to you?
grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u
lscpu | grep -i -E 'virtual|hypervisor'

# 3. The definitive check
sudo apt update && sudo apt install -y cpu-checker
kvm-ok

# 4. The device node the whole stack depends on
ls -l /dev/kvm

If instance dey work, e go print vmx or svm. kvm-ok go say KVM acceleration can be used, and /dev/kvm go dey root:kvm mode 660. If you see the flag but the device node no dey, load the module manually and check the kernel log:

sudo modprobe kvm_intel     # or kvm_amd
sudo dmesg | tail -n 20

One file dey cause wahala because many people dey misread am:

cat /sys/module/kvm_intel/parameters/nested   # Y or N

Inside your VPS, na this setting for your KVM module, and e dey control if L2 guest fit do nesting for third level. E no dey tell you if L0 enable nesting for you — /proc/cpuinfo and kvm-ok na dem go answer that one. The nested parameter na the knob wey you go set for machine wey you own:

echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel

System no go allow you remove module if VM dey run, so make you shut down all guests first.

Why most VPS hosts dey leave am off

  • Live migration. If dem give you vmx, e mean say dem expose CPU model wey carry the flag. Guest OS wey depend on those CPU features no fit migrate safely to machine wey CPU no get dem. Host wey dey move customers around by migration no fit do that thing once dem enable nesting.
  • Attack surface. The nested VMX/SVM paths na one of the most complex code inside kernel virtualization layer, and e get many CVE history.
  • L0 may not be KVM. If systemd-detect-virt print vmware, xen or microsoft, nesting rules na for that stack, no be KVM.

If your instance no get flag? Ask support (some dey enable am for per-VM), pick plan wey talk about nesting, or move to dedicated box. Everything wey follow for this tutorial assume say you get root for machine wey show the flag.

Running an L2 guest with libvirt

sudo apt install -y qemu-system-x86 libvirt-daemon-system virtinst ovmf
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm "$USER"   # log out and back in

virt-install \
  --name guest1 \
  --memory 2048 \
  --vcpus 2 \
  --cpu host-passthrough \
  --disk path=/var/lib/libvirt/images/guest1.qcow2,size=20,format=qcow2,bus=virtio \
  --network network=default,model=virtio \
  --os-variant debian13 \
  --location https://deb.debian.org/debian/dists/trixie/main/installer-amd64/ \
  --graphics none \
  --console pty,target_type=serial \
  --extra-args 'console=ttyS0,115200n8'

You no need graphical session. Serial install dey take time, so start am inside persistent shell: di same tmux workflow wey dey keep Claude Code sessions alive on a VPS dey keep virt-install console attached even if SSH connection drop. If --os-variant debian13 fail, your osinfo-db old pass di release — run osinfo-query os and pick name wey dey exist. --cpu host-passthrough dey forward vmx down into L2, and you only need am if L2 must virtualize inside. Use virsh autostart guest1 make di guest boot-safe.

Di virtio bus for disk and NIC no be decoration: emulated IDE and e1000 devices dey trap into di hypervisor more often than virtio queues, and for nesting, every trap go cost twice.

Networking: the part tutorials skip

Your VPS get one public IP and e dey behind one fabric wey dey filter unknown MAC addresses. Two things go happen because of this.

To bridge L2 guests onto the public network usually no go work. If you put br0 on the public NIC, and you give the guest its own MAC, you go see ARP go out but nothing go come back — the provider switch dey drop frames from any MAC wey dem no lease to you. If na this one you dey see, stop to dey debug the bridge; na how the mechanism take work.

Use the NAT network instead. libvirt dey carry default: virbr0, 192.168.122.0/24, and dnsmasq leases, so outbound work go start immediately. For inbound, terminate TLS on L1 and proxy am in — the certificate paths wey dey below come from how to issue a Let's Encrypt certificate with Certbot on Nginx:

server {
    listen 443 ssl;
    server_name lab.example.com;

    ssl_certificate     /etc/letsencrypt/live/lab.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lab.example.com/privkey.pem;

    location / {
        proxy_pass http://192.168.122.50:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Give the guest one static lease first (virsh net-edit default) so that the address for that proxy_pass go stay one place.

Management interfaces no suppose dey for internet: VNC on 5900 and the Proxmox web UI on 8006 suppose dey for loopback, wey you go reach via SSH tunnel (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) or through self-hosted WireGuard VPN into the VPS, wey go put the whole 192.168.122.0/24 guest range one private hop away. Keep the firewall narrow — sudo ufw allow 22,80,443/tcp, nothing else. If guests lose outbound connectivity immediately after you enable ufw, the main problem na usually DEFAULT_FORWARD_POLICY="DROP" for /etc/default/ufw — set am to ACCEPT and reload ufw.

Proxmox for VPS

Proxmox VE 9 dey run for Debian 13 base, so you fit install am for Debian VPS by adding the pve-no-subscription repository and the proxmox-ve package. Copy the repository and keyring lines from Proxmox official documentation — if you use URL from old blog post, the install go fail.

The packages no be the hard part. Proxmox want make vmbr0 bridge to physical NIC, but dat one go cause de MAC-filtering problem wey we talk above. De way wey dey work for VPS na to use NAT'd or routed vmbr0 wey no get physical port attached, put guests for private range, and use DNAT rules or reverse proxy for de host for any public service. If de public services na containers instead of VMs, Traefik wey dey front multiple apps from one Docker Compose file fit do de same routing work with automatic certificates. Make you snapshot /etc/network/interfaces first: if you mess up de bridge definition, you fit lock yourself out of de machine and you fit no get access to de console.

Performance, wey be true

Nested slower than single-level, and the reason for am no be everywhere: memory access no be where the cost dey, na exits dey cause am. Since EPT/NPT dey, L0 dey maintain shadow page tables for L2 and normal memory reads dey run for hardware speed. Wetin dey cost na every operation wey leave guest mode — I/O, timer interrupts, MMIO, inter-processor interrupts — because L2 exit dey get handle for L0 and e fit go back through L1. CPU-bound work wey dey use data wey already dey RAM dey look like native; anything wey plenty with syscalls, packets and disk I/O go feel the layers.

So: use virtio devices everywhere. And your qcow2 file dey live for disk wey provider don already virtualize — two thin-provisioning layers stack, where cache=none on the guest disk dey stop the same blocks from dey inside two page caches at once. No benchmark numbers for here: measure your own workload for your own instance.

Failure modes, and the strings you will see

INFO: /dev/kvm does not exist / KVM acceleration can NOT be used from kvm-ok. Either the module no load, or the flag no expose. Check /proc/cpuinfo first.

kvm: disabled by bios in dmesg. For bare metal, flip the VT-x/SVM toggle for firmware. Inside a VPS, epp means L0 no dey give you the extensions, and nothing wey you type for guest fit change am.

modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. The CPU wey your kernel see no get vmx — once again, na L0 decision.

Could not access KVM kernel module: Permission denied. Na permission issue, no be hardware. ls -l /dev/kvm suppose show group kvm, mode 660; add yourself to that group and start new login shell, because group membership no dey work for session wey don already dey run.

kvm: Device or resource busy when QEMU start. Another hypervisor module dey hold the CPU: run lsmod, look for vboxdrv or VMware modules alongside kvm_intel, and unload the one wey you no want.

/var/run/libvirt/libvirt-sock: No such file or directory from virsh. The daemon don down: sudo systemctl enable --now libvirtd.

Proxmox: KVM virtualisation configured, but not available. A guest don tick KVM acceleration for host wey no fit provide am. Fix the nesting, or untick am and accept emulation.

Android emulator: x86_64 emulation currently requires hardware acceleration! /dev/kvm again — usually na the group case.

No error at all, and everything dey slow like snail. QEMU wey no get accelerator flag go fall back to TCG, its software emulator. E correct, but e slow — boot wey suppose take seconds go take minutes. Pass -accel kvm explicitly, so QEMU go stop with error instead of to dey quietly emulate.

A guest vanish mid-run. Look for Out of memory: Killed process ... qemu-system-x86_64 for dmesg. L2 guest na process for L1, and OOM killer go treat am like any other process. L2 RAM dey come from L1 fixed allocation — e no dey borrow from host.

Operating it: backups, upgrades, limits

Backups. If you copy running guest qcow2, the image go corrupt. You fit use virsh shutdown guest1 and copy, or take external snapshot (virsh snapshot-create-as guest1 snap1 --disk-only --atomic) so that all new writes go flow go overlay while you dey copy the static base, then use virsh blockcommit fold am back. Move the copies go outside the VPS — snapshot for inside the same disk no dey protect against anything.

Upgrades. apt full-upgrade dey install new kvm_intel/kvm_amd modules, but the running kernel go still hold the old ones until you reboot. Make you keep the previous kernel installed and re-run kvm-ok after every kernel change: if host come back without vmx, e dey just one boot entry away from work again.

Where this stops scaling. One public IP mean say every L2 service go reach the world through proxy or DNAT rule for L1. Live migration no dey for the menu. If CPU contention start, nested exit path na the first thing wey go feel the wahala. And hypervisor wey get many guests na machine wey RAM don finish — nested VMs no fit use overcommit bypass fixed allocation. When lab grow pass that level, the answer no be to build taller nested stack; the answer na dedicated box where you be L0 and none of this matter go apply.

FAQ

I need nested virtualization to run Docker for VPS?

No. Containers dey share your VPS kernel and dem no dey open /dev/kvm, so plain instance wey no get vmx or svm flag go run Docker and Docker Compose fine. Nesting only matter when you want second kernel: like Proxmox lab, Windows guest, Firecracker microVMs, Android emulator, or CI runners wey dey boot VM images.

How I go check if my VPS support nested virtualization?

Run grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u, then run kvm-ok from cpu-checker package. If e dey work, e go print vmx (Intel) or svm (AMD), kvm-ok go report KVM acceleration can be used, and /dev/kvm go dey with group kvm and mode 660. No look /sys/module/kvm_intel/parameters/nested for this question — that file na your own KVM module dey describe, no be wetin provider's hypervisor give you.

Why most VPS providers dey disable nested virtualization?

To expose vmx mean say dem dey give guest CPU model wey get that flag, and guest wey depend on those CPU features no fit do live-migration to another machine wey CPU no get dem — provider wey dey move customers around to balance nodes no go want do that one. The nested VMX/SVM code paths also get many CVE history. Some hosts still dey enable am for per-VM if you ask dem, and others dey list nesting as a plan feature.

My nested VM no get network for public bridge. Wetin dey wrong?

The provider switch dey drop frames from MAC address wey dem never lease to you, so L2 guest wey bridge for public NIC go send ARP but no go hear anything back. Stop debugging br0 — use libvirt's NAT default network (virbr0, 192.168.122.0/24), give the guest static lease, and use reverse proxy or DNAT rule for the VPS itself to publish anything public.

How much slower nested VM dey?

The wahala dey for VM exits, no be for memory access. When EPT/NPT dey work, ordinary reads and writes inside L2 dey run for hardware speed, but I/O, timer interrupts, MMIO, and IPIs go dey handled by L0 and dem fit bounce back through L1. CPU-bound work wey use data for RAM dey look like native; but syscall-, packet-, and disk-heavy workloads go feel every layer. Use virtio devices everywhere and cache=none for guest disks, then measure your own workload.

#nested-virtualization#kvm#proxmox#vps#qemu#libvirt