Containers vs VMs
Proxmox runs two kinds of guests: VMs (KVM, full virtualization) and containers (LXC, operating-system virtualization). They look similar in the UI — both get IDs, both start and stop — but they're different machines under the hood, and picking the right one saves real resources.
The difference, plainly
A VM pretends to be an entire computer: virtual BIOS, virtual disk, virtual network card, and its own kernel. It can run any OS — Linux, Windows, BSD — because from the guest's point of view, the hardware is real.
A container pretends to be an operating system, not a computer. It shares the host's kernel and just gets its own isolated slice of everything else: its own files, its own processes, its own network address. No virtual hardware, no second kernel.
Consequences:
| VM (KVM) | Container (LXC) | |
|---|---|---|
| Guest OS | Anything | Linux only (shares host kernel) |
| Memory overhead | A full OS worth | Almost none |
| Boot time | Tens of seconds | About a second |
| Isolation | Strong (hardware boundary) | Good (kernel namespaces), weaker |
| Density | Fewer per host | Many per host |
The apartment-building analogy again: VMs are separate apartments with their own plumbing. Containers are roommates with lockable bedrooms sharing one kitchen — lighter, but you're all using the same stove.
When a container is enough
If the workload is a Linux service — a web app, a database, a media server, a DNS server, a build box — a container does the job with a fraction of the RAM. Home labs run most of their services in containers for exactly this reason.
Reach for a full VM when: the guest isn't Linux (Windows, BSD), you need a different kernel version than the host's, you want the strongest isolation, or you're testing OS installs themselves.
Making a container
Containers are born from templates, not ISOs. Get one:
-
Click your node →
local (pve)→ CT Templates tab → Templates. Pick a Debian or Ubuntu template and download it. (These come from Proxmox's template repository — from the docs.) -
Click Create CT (top right). The wizard mirrors the VM one: ID, hostname, password, template, disk size, CPU, memory, network on
vmbr0, DNS. -
Start it. It's up in about a second.
The pct basics
pct manages containers the way qm manages VMs (verified
against the official pct(1) man page — every command below
exists there):
pct list # all containers on this node
pct start 101
pct stop 101
pct destroy 101 # delete it entirely
pct enter 101 # open a shell inside the container
pct exec 101 -- df -h # run one command inside it
pct config 101 # show its configuration
Honestly labeled: syntax verified against the official man page; not executed in this build environment.
pct enter is the container equivalent of SSHing in — a root
shell inside the guest, no network needed.
Privileged vs unprivileged
New containers default to unprivileged: the container's
root maps to a nobody-user on the host, so a container
breakout gains almost nothing. This is what you want. Privileged
containers exist for special cases (some nested-Docker setups);
don't reach for them casually.
The one idea to keep
VMs virtualize hardware; containers virtualize the operating system. Same Linux workload, far less overhead in a container. Use VMs for other operating systems and maximum isolation; containers for Linux services. Next: where all these disks actually live, in Storage.