KVM vs OpenVZ: Why Docker or WireGuard Won't Run on Your VPS

· 6 min read · 6 views · Getwebup

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 permitted
  • docker: Error response from daemon: error creating overlay mount: invalid argument
  • Cannot open TUN/TAP dev /dev/net/tun: Operation not permitted when starting OpenVPN or WireGuard
  • Sysctl changes that silently don't apply, like net.ipv4.ip_forward resetting on reboot
  • A kernel version in uname -r that 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-virt

If 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 tun module 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:

CommandWhat it tells you
systemd-detect-virtPrints kvm, openvz, lxc, or none (bare metal)
cat /proc/user_beancountersExists only on OpenVZ — if this file is there, you're in an OpenVZ container
dmesg | grep -i virtualOften shows the hypervisor on KVM; usually empty or restricted on OpenVZ
ls /dev/net/tunIf 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

SymptomRoot causeFix
Docker won't start / overlay mount errorsShared kernel lacks required overlay/cgroup featuresAsk your provider to enable them host-side (rarely possible), or migrate to a KVM plan
WireGuard/OpenVPN TUN errorHost hasn't loaded or exposed the tun module to your containerRequest 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 intoOnly solvable on KVM — there's no per-container workaround
Sysctl values reset on rebootValue is host-controlled, not container-controlledSet it in a boot script as a workaround, or move to KVM for a permanent fix

Migrating From OpenVZ to KVM Without Losing Data

  1. Provision the new KVM VPS and confirm with systemd-detect-virt before doing anything else.
  2. 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.
  3. Re-export databases with mysqldump and import fresh rather than copying MySQL's raw data directory across the two virtualization types.
  4. 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.
  5. Test Docker, WireGuard, or whatever failed originally on the new box before you cut DNS over.
  6. 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-virt on 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.

Questions people actually ask