Proxmox LXC vs VM explained in one line: run an unprivileged LXC container for Linux services that can live on the host’s kernel, and run a VM for anything that needs its own kernel, Windows or BSD, live migration, full PCI passthrough, or a Docker stack you want properly isolated. On an N100 mini-PC, that usually means mostly containers plus one VM.
If you came from ESXi, where everything is a VM, containers are the new concept here; the VMware vSphere to Proxmox VE migration guide covers the rest of that move.
What is the actual difference between an LXC container and a VM?
An LXC container is a group of Linux processes running on the Proxmox host’s own kernel, fenced off with namespaces, cgroups, AppArmor and seccomp. A VM is a complete emulated computer under QEMU/KVM, with its own firmware, virtual hardware and kernel. Nearly every other difference between the two follows from that one fact.
The Proxmox Container Toolkit documentation says containers “use the kernel of the host system that they run on, instead of emulating a full operating system.” There’s no second kernel, firmware or bootloader to start, and no emulated disk controller or NIC. Its memory limit is a cgroup cap, not a block of RAM handed to a guest kernel that will happily fill it with page cache.
The price is that shared kernel. The Linux Container wiki page states that “only Linux distributions can be run in Proxmox Containers,” so FreeBSD and Windows are out. If something needs a different kernel version, a kernel module or a sysctl the host doesn’t set, you configure it on the host, and it applies to every container at once. The same page’s security section is blunt: the shared kernel “exposes an attack surface for malicious users.”
A VM carries more overhead but none of those limits. The QEMU/KVM chapter describes QEMU as a hypervisor that “emulates a physical computer,” so unmodified operating systems run as if on bare metal. Paravirtualized devices cut most of that overhead. Proxmox’s docs say the VirtIO disk controller doubles sequential write throughput over an emulated IDE controller, and the VirtIO NIC delivers up to three times the throughput of an emulated Intel E1000.
LXC vs VM at a glance
| LXC container | VM (QEMU/KVM) | |
|---|---|---|
| Kernel | Shared with the Proxmox host | Its own |
| Guest OS | Linux distributions only | Linux, Windows, BSD, appliance images |
| Isolation boundary | Namespaces, cgroups, AppArmor, seccomp | Hardware virtualization |
| Live migration | No; restart migration only | Yes, unless devices are passed through |
| Memory | cgroup limit; unused RAM stays with the host | Assigned to the guest; ballooning can reclaim some |
| Hardware access | Device nodes via devX, shareable | PCI passthrough, exclusive to one VM |
| Default backup scope | Root disk only; bind and device mounts never | Its virtual disks |
| Docker | Works with nesting; not the recommended path | Recommended for isolation and live migration |
Where LXC wins
Density on small hardware. A low-power mini-PC has no cores or RAM to waste. Each VM runs its own kernel and page cache, and that overhead adds up across five small VMs. The same five services as containers cost little more than the services themselves.
Sharing an iGPU. This is the big one for media servers. The devX option in the pct manual passes a device node such as the host’s render node into a container, and you can give the same node to more than one container:
# Give container 101 the host's render node; set gid to the render group inside the CT
pct set 101 --dev0 path=/dev/dri/renderD128,gid=<render-gid-in-container>
PCI passthrough to a VM is the opposite. The PCI passthrough wiki notes that “the device is not available to the host anymore” and that “VMs with passed-through devices cannot be migrated.” If Jellyfin and a second service both want hardware transcoding from one Intel iGPU, containers are the easy answer.
NAS data via bind mounts. Mount the NFS or SMB share once on the host, then bind-mount it into the containers that need it. The Linux Container page lists accessing an NFS mount from the host in the guest as a bind-mount use case. The catch is UID mapping, covered below.
Where a VM wins
Anything that isn’t Linux, or isn’t your kernel. OPNsense (FreeBSD-based), Windows, and appliance distributions shipped as whole-disk images all need a VM. So does software that wants a specific kernel or loads its own modules.
Docker. Docker runs inside an LXC container once you enable the nesting feature, plus keyctl for an unprivileged one; the pct.conf reference says keyctl “is required to use docker inside a container” and warns it forces a choice between systemd-networkd and Docker. Proxmox’s own guidance is still that “for use cases demanding maximum isolation and the ability to live-migrate, nesting containers inside a Proxmox QEMU VM remains a recommended practice.” Proxmox VE 9.1 added OCI image support, with application containers flagged as a technology preview per the release notes. Worth watching, but not yet a reason to move a working compose stack.
The opinionated take: Docker-in-LXC stacks two container runtimes on the host kernel, both depending on cgroup and AppArmor behavior a host upgrade can change. One Debian VM running your compose file is boring and survives upgrades without a forum search. The RAM you’d save rarely limits a homelab.
Live migration and HA. The Linux Container page says running containers can’t be live-migrated because of technical limitations. The alternative is a restart migration (pct migrate <vmid> <target> --restart), which the docs say normally costs some hundreds of milliseconds of downtime. VMs migrate online, and an HA failover of a container is always a restart. If a second node is coming, the Proxmox cluster planning guide covers the storage and quorum side. On a single mini-PC, there’s nowhere to migrate to anyway.
Untrusted or internet-facing workloads. A kernel bug reachable from inside a container is a bug in your host. To break out of a VM, an attacker also needs a hypervisor flaw, which is a narrower attack surface. For a public-facing service you didn’t write and don’t audit, pay the VM tax.
Whole devices. An HBA for a NAS VM, a dedicated NIC for a firewall, or a discrete GPU for local AI all call for PCI passthrough, and you accept losing migration for that guest.
Should LXC containers be privileged or unprivileged?
Unprivileged, which is already the Proxmox default. Root inside the container maps to an unprivileged UID on the host, so a container escape lands as an ordinary high-numbered user, not as host root. The LXC project’s security page calls unprivileged containers “safe by design” and says privileged containers “aren’t and cannot be root-safe.”
Upstream won’t treat escapes from privileged containers as CVE-worthy either. The cost of unprivileged mode lands on bind mounts. The unprivileged containers wiki explains that root “became uid 100000, 1 will be 100001 and so on,” and unmapped files show up as nobody (65534).
A NAS share owned by UID 1000 on the host looks wrong inside the container. Either chown the host-side data to the mapped UID (101000 for container UID 1000), or write a custom lxc.idmap in the container config. Either one is an afternoon of yak-shaving the first time. Don’t switch the container to privileged to dodge it.
Storage and backups: what container backups skip
This is the part that bites at month nine. The Backup and Restore chapter says that by default “additional mount points besides the Root Disk mount point are not included in backups.” Device and bind mounts are never backed up, because Proxmox’s storage layer doesn’t manage them. If your Jellyfin metadata or Home Assistant config lives on a bind mount, your nightly vzdump job doesn’t contain it.
Either keep application state on the root disk or a storage-backed mount point with backup enabled, or treat bind-mounted data as the NAS’s problem and back it up there. Snapshot-mode container backups also need every backed-up volume on snapshot-capable storage, so check that before you trust the job.
VM backups are simpler: the job captures the guest’s virtual disks. With the QEMU guest agent enabled, snapshot mode freezes the guest filesystem first for a more consistent image.
Whatever you run, do a restore drill. Restore one container and one VM to new IDs with networking disconnected, boot them, and confirm the application data is actually there. A backup job that reports success and restores an empty config directory isn’t a backup.
Which one should you pick?
For a typical N100-plus-NAS homelab, use unprivileged LXC containers for single-purpose Linux services such as DNS filtering, a reverse proxy, Jellyfin with iGPU transcoding and the *arr apps. Run one Debian VM for your Docker compose stack. Use VMs for anything non-Linux, anything internet-exposed you don’t trust, and anything that needs a whole device passed through.
For borderline cases, use this tie-breaker: if a kernel bug in this service taking down the host would ruin your week, give it a VM. If you’d just restart it and move on, a container is fine.
A container-heavy host makes kernel patching matter more, since every container rides on that one kernel. Apply host updates promptly.
FAQ
can you run docker in a proxmox lxc container
Yes, Docker runs inside an LXC container once you enable the nesting feature, plus keyctl for unprivileged containers. Proxmox still recommends a QEMU VM for application containers when you need maximum isolation or live migration. A VM also keeps Docker insulated from host kernel and AppArmor changes that arrive with Proxmox upgrades.
can i run windows in an lxc container on proxmox
No. LXC containers share the Proxmox host’s Linux kernel, so they can only run Linux distributions, and Proxmox’s documentation explicitly rules out Windows and FreeBSD. Windows, OPNsense, pfSense and any other non-Linux system must run as a QEMU/KVM virtual machine, ideally with VirtIO drivers for disk and network performance.
is lxc faster than a vm in proxmox
Usually, for Linux services, because a container runs directly on the host kernel with no emulated hardware and no second kernel. The gap narrows with VirtIO disk and network devices, which avoid most emulation overhead inside a VM. Choose on isolation, operating system and migration needs first, raw speed second.
can you convert an lxc container to a vm in proxmox
Not directly. A container has no bootloader, kernel or disk layout of its own, so Proxmox offers no one-click conversion between the two. The practical route is to build a fresh VM, install the same service, and copy its configuration and data across. That’s one more reason to keep application data on clearly separated storage.
Related across the network
- Proxmox VE Homelab Roadmap: What to Set Up, In What Order — proxmoxguide.com
- Proxmox on a Mini PC: LXC vs VM, Storage and Backups — minilabhq.com