You spin up a fresh VPS, run apt install docker.io, and Docker won't start. Or you try to bring up a WireGuard tunnel and get a cryptic TUN device error. You've checked your commands ten times — they're correct. The problem isn't your config. It's the box underneath you.
The Symptom: Kernel Features That Just Aren't There
A few error messages point straight at this issue, even though none of them mention virtualization by name:
modprobe: ERROR: could not insert 'tun': Operation not permitteddocker: Error response from daemon: error creating overlay mount: invalid argumentCannot open TUN/TAP dev /dev/net/tun: Operation not permittedwhen starting OpenVPN or WireGuard- Sysctl changes that silently don't apply, like
net.ipv4.ip_forwardresetting on reboot - A kernel version in
uname -rthat never matches what you installed, no matter how many times you reboot
If any of that looks familiar, run one command before you touch anything else:
systemd-detect-virtIf it prints openvz or lxc, you've found the cause. If it prints kvm, the problem is somewhere else and you can rule this article out.
The Cause: Not Every "VPS" Gives You a Real Kernel
"VPS" gets used as one label for two genuinely different technologies, and the difference matters a lot more than most buying guides admit.
OpenVZ and LXC: containers, not virtual machines
OpenVZ (and its modern cousin, LXC) is operating-system-level virtualization. Every VPS on the node shares the host's actual kernel. What you get is closer to a heavily isolated set of processes and a filesystem than a real machine. That's why it's cheap to run and why providers can pack a lot of accounts onto one physical server.
The catch: you can't load your own kernel modules, because there's no "your own kernel" — you're borrowing the host's. That single fact explains almost every symptom above:
- No
tunmodule loaded on the host (or blocked for tenants) means no WireGuard, no OpenVPN, sometimes no IPsec. - Docker relies on kernel namespaces and cgroups that OpenVZ's own containerization already occupies, so nested containers frequently fail or behave inconsistently.
- Some sysctl values are host-wide, not per-container, so your changes get silently ignored or reset.
- Disk and RAM limits are frequently oversold, because the host can't always tell how much a container will actually use until it uses it.
KVM: an actual virtual machine
KVM (Kernel-based Virtual Machine) is full hardware virtualization. Your VPS boots its own kernel, has its own virtualized CPU, RAM, and disk, and behaves like a physical server in every way that matters. You can load kernel modules, run Docker (including Docker-in-Docker if you're determined), build custom kernels, and set any sysctl you like. It costs more to run per account because there's no shared-kernel trick to overcommit resources as aggressively — which is exactly why it's more predictable.
How to Check What You're Actually On
Don't take a provider's marketing page's word for it. Check directly:
| Command | What it tells you |
|---|---|
systemd-detect-virt | Prints kvm, openvz, lxc, or none (bare metal) |
cat /proc/user_beancounters | Exists only on OpenVZ — if this file is there, you're in an OpenVZ container |
dmesg | grep -i virtual | Often shows the hypervisor on KVM; usually empty or restricted on OpenVZ |
ls /dev/net/tun | If missing and you can't create it, TUN is disabled at the host level |
On Getwebup's VPS plans this always resolves to kvm — we don't sell container-based "VPS" plans precisely because of the support tickets they generate.
The Fix, Symptom by Symptom
| Symptom | Root cause | Fix |
|---|---|---|
| Docker won't start / overlay mount errors | Shared kernel lacks required overlay/cgroup features | Ask your provider to enable them host-side (rarely possible), or migrate to a KVM plan |
| WireGuard/OpenVPN TUN error | Host hasn't loaded or exposed the tun module to your container | Request tun be enabled per-container (some OpenVZ hosts allow this), otherwise move to KVM |
| Custom kernel module needed (ZFS, custom netfilter, etc.) | No independent kernel to load it into | Only solvable on KVM — there's no per-container workaround |
| Sysctl values reset on reboot | Value is host-controlled, not container-controlled | Set it in a boot script as a workaround, or move to KVM for a permanent fix |
Migrating From OpenVZ to KVM Without Losing Data
- Provision the new KVM VPS and confirm with
systemd-detect-virtbefore doing anything else. - Copy data over with
rsync -avz --progress /var/www/ user@new-server-ip:/var/www/rather than a raw disk image — you can't image an OpenVZ container onto a KVM host anyway, since the underlying disk formats aren't compatible. - Re-export databases with
mysqldumpand import fresh rather than copying MySQL's raw data directory across the two virtualization types. - Reinstall your web stack (Nginx/Apache, PHP-FPM, cPanel if applicable) on the new host rather than trying to carry over host-level configuration — package versions and paths often differ between providers.
- Test Docker, WireGuard, or whatever failed originally on the new box before you cut DNS over.
- Lower your DNS TTL to 300 seconds a day ahead of the cutover, then point the A record at the new KVM server once everything checks out.
Prevention: Check Before You Buy, Not After You're Stuck
The mistake almost everyone makes is finding this out after they've already built something on the box. Before committing to a VPS plan:
- Ask the provider directly: "Is this KVM or container-based (OpenVZ/LXC)?" A provider that won't give you a straight answer is telling you something.
- If the plan is unusually cheap compared to others with the same specs, assume container-based until proven otherwise — the pricing gap is exactly the cost KVM doesn't let providers cut.
- If you already know you need Docker, VPN tunnels, or a custom kernel, treat KVM as a hard requirement, not a nice-to-have.
Prevention Checklist
- Run
systemd-detect-virton day one of any new VPS, before you deploy anything. - Keep a note of which provider/plan gave you which result — it saves the next round of troubleshooting.
- If you're testing Docker or VPN software, do it in the first hour, not the first week, so a migration is still cheap if you need one.