Blog

Proxmox VE: LXC or a Full VM?

Proxmox VE with LXC containers and VMs in a homelab

When the secondhand 1U arrived, I didn't just pile all the Docker onto bare-metal Ubuntu — I installed Proxmox VE. The goal was to slice one physical machine into test environments, soft-router experiments, and long-running services so that when one breaks, the others don't take the hit. Once the web UI was up, the first real question wasn't "where's the create-VM button" but whether each workload should be an LXC container or a KVM VM. Get that choice wrong and you spend the rest of your time patching nesting and permission issues.

Start with a decision table

Question Lean LXC Lean VM
Need a separate kernel or custom kernel modules? No Yes
Running nested containers like Docker / k8s? Avoid if you can Fine, as a dedicated host
RAM budget tight? Yes, want many small systems No, willing to pay for isolation
Need Windows or non-Linux guests? No Yes
Network experiments needing strong isolation and full rollback? Lightweight proxies can be LXC Soft routers are safer as VMs
Want clean "whole machine" snapshot and migration semantics? System containers are enough Serious databases lean VM

One-line comparison: a VM is hardware virtualization with its own kernel — strong isolation, bigger overhead. LXC shares the host kernel — light, close to a beefed-up chroot. Need your own kernel modules, awkward Docker-in-Docker, or testing another distro's kernel → VM. Just want an isolated userspace to run services and save RAM → LXC.

Scenario A: soft routers and "break it, roll it back"

OpenWrt and other soft routers live in a VM for me. Not because LXC can't run them, but because when a network-stack experiment fails, the psychological cost of a whole-machine snapshot rollback is lower. NIC passthrough, multiple bridges, and VLAN sub-interfaces also have most of their docs and community experience written for VMs. One warning: after NIC passthrough the host loses that port — if your secondhand 1U has only one management port, draw the diagram before clicking passthrough, or you'll be hooking up a monitor in the wiring closet.

The default vmbr0 bridges the physical NIC, putting VMs on the same subnet as the host — fine for a home start. VLAN-aware bridges come later. Anyone who's scrambled their only management port once understands why out-of-band management is a rack necessity.

Scenario B: a long-term Docker host

For long-lived compose stacks, I prefer a dedicated VM — or a dedicated physical box — over Docker inside a privileged LXC. Nested containers plus storage-driver and cgroup version issues make it impossible to tell whether Proxmox or Docker is to blame. Put a regular Linux in a VM, run Docker there, and the boundary stays clean: vzdump backs up the whole host and migration semantics are obvious.

Some people live with all-LXC. After being burned by "privileged LXC + nesting," I'd rather stay conservative. One-off test Docker environments can be cloned from a short-lived VM template and deleted when done — don't stack experiments on top of production containers.

Scenario C: lightweight tools and jump boxes

DNS test instances, temporary jump hosts, a static docs site, a dedicated fail2ban observer — these are perfect LXC candidates: seconds to start, tiny RAM footprint, fast template cloning. No separate kernel needed, no nested containers; you just need isolation down to "another CT blowing up doesn't drag down the host's userspace." Overcommit resources a bit more aggressively here. Just don't apply the same overcommit fantasy to latency-sensitive game servers and databases.

A template strategy pays off: build one minimal Debian/Ubuntu CT template with common tools and your SSH public key preloaded, then clone and change the IP for each new job. Experiments that fail get destroyed without the physical-machine agonizing over "should I keep this one around." That low psychological cost is exactly why I shove messy experiments into LXC instead of polluting the Docker host VM.

Scenario D: databases and "serious tier" data

Postgres and data services that need clear crash-consistency expectations more often land in a VM. Not because LXC can't run a database, but because "whole disk" narratives are simpler for snapshots, backups, and migrations, and they layer cleanly with restic and logical dumps later. Running a DB in LXC works, but be ready for extra considerations around host kernel upgrades and CT feature flags.

Windows experiments have no choice but a VM. GPU passthrough and vendor toolchains follow the same VM decision path.

How storage and backups follow the choice

Proxmox's system disk is an SSD; the big disk goes to ZFS or LVM-thin for virtual disks. Both LXC and VM disk files live there, and the choice feeds back into backup granularity: whole-VM vzdump dumps are big but semantically clean; LXC is small and fast but makes it too easy to think "copying a rootfs layer equals recoverable app." Important VMs get vzdump on a schedule to another box or NFS — don't rely on local snapshots on the same disk as your disaster recovery. ISO and cloud-image templates go in local storage; import once and stop reinstalling everywhere.

A recovery only counts once you've drilled it: delete a test VM → restore from backup → change the IP → check the service comes back. Memory and CPU overcommit make you feel like you can always spin up one more box; the bill comes due as overheating and OOM — so cut some slack to VMs already flagged "serious tier." I pin minimum guarantees for the router VM and database VM and push the overcommit pressure onto disposable tool containers.

When you shouldn't be using Proxmox at all

If you have one small N100 running three compose stacks, bare-metal Ubuntu is simpler. Virtualization buys you isolation and snapshots; it costs an extra layer of storage and networking concepts. Match the machine to the scenario before adopting it — don't build a "data center" just to feel like one. For my secondhand 1U, the decision table outputs something concrete: a router VM, a Docker host VM, a pile of tool LXCs, and a database VM — not "all LXC to save RAM" or "all VMs, one size fits all."

← Back to Blog