KVM vs OpenVZ: Why Docker or WireGuard Won't Run on Your VPS
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.
Frequently asked questions
Is OpenVZ always bad?
No. For a static website, a small database, or a low-traffic app that never needs Docker or a VPN tunnel, OpenVZ can run fine and cost less. The problem only shows up when your workload needs kernel-level features the container can't provide.
Can a provider just "turn on" TUN or Docker support for my OpenVZ container?
Sometimes, for TUN specifically — some OpenVZ hosts allow the tun module per-container if you ask support. Docker support is much harder to add after the fact because it depends on kernel features OpenVZ's own containerization already uses for something else.
How do I know if a VPS plan is KVM before I buy it?
Check the provider's plan page for the word "KVM" explicitly, or ask their sales/support team directly. If the answer is vague or they only mention "virtual private server" without naming the hypervisor, assume it may be container-based and confirm before you commit.
Does switching to KVM fix slow performance too?
Sometimes, but not always for the same reason. KVM gives you dedicated kernel resources, but overselling of CPU/RAM can still happen on a badly run KVM host. Virtualization type fixes kernel-feature problems; it doesn't guarantee performance on its own.
Will migrating from OpenVZ to KVM break my site?
Not if you migrate data and re-provision the stack rather than trying to copy the container image directly — the underlying disk and kernel are different enough that a raw copy won't boot. Follow the rsync + fresh database import + reinstall approach above.