This episode covers LXC as the container (CT) engine of Proxmox VE: the CT architecture on top of liblxc, the fact that PVE 9.2 ships LXC 7.0 LTS, unprivileged CT as the default, and the practice of Docker-in-LXC with nesting and nested virtualization.

So far you've managed LXC via the CLI on a regular Linux host. But there's a far more widely used LXC manager: Proxmox VE (PVE) — a virtualization platform that runs LXC as its container (CT) engine alongside KVM VMs. In episode 12 we look at how PVE uses LXC, what's "under the hood" of a CT, and how to run Docker inside one. This is the bridge from raw LXC to managed virtualization.
PVE uses LXC as its container engine. Every CT in Proxmox is actually an LXC container managed through PVE's API and web interface, not via direct lxc-create. Behind the scenes, PVE writes the LXC config (in a format similar to what we've covered throughout this series) and calls liblxc through its wrapper.
That's why all the concepts you've already mastered — namespaces, cgroups, bridge networking, storage, snapshots — apply directly in PVE. Only the interface changes: the GUI, REST API, and the pct CLI.
pct list
pct status 100
pct config 100An important fact for you: Proxmox VE 9.2 ships LXC 7.0 LTS as its container engine. That means all the 7.0 LTS security fixes — including the CVE-2026-39402 fix (episode 16) — are already in PVE 9.2. When using PVE in production, verify the LXC version inside it:
lxc --version
pveversionSince PVE 5, unprivileged CT is the default when creating new containers — exactly the direction we recommended in episode 5. In the GUI, the "Unprivileged container" option is checked by default; in the pct create CLI there's a flag:
pct create 100 local:vztmpl/ubuntu-24.04-standard_24.04-1_amd64.tar.zst \
--storage local-lvm \
--features nesting=1 \
--unprivileged 1 \
--net0 name=eth0,bridge=vmbr0,ip=dhcpA few things to note about unprivileged CTs on PVE:
fuse, loop devices, or similar, you'll need extra features (keyctl, nesting, fuse, etc.) via pct set or --features.A common homelab scenario: you want an LXC container as an isolated "server node", then run Docker inside it for applications. This combines Docker's convenience with system container isolation. On PVE, this pattern is called Docker-in-LXC and is recommended with nesting enabled.
nesting=1): allows the container to create additional namespaces and mounts inside itself — a key requirement for Docker inside a CT to run its own containers (Docker uses namespaces).Enable nesting for CT 100:
pct set 100 --features nesting=1
pct reboot 100Once nesting is active, install Docker inside the CT like on a regular Ubuntu host:
pct enter 100
apt update && apt install -y docker.io
systemctl enable --now docker
docker run --rm hello-worldWarning
Docker inside LXC needs an updated AppArmor profile so the default LXC policy doesn't block Docker operations (we cover the details in episode 13). If docker run fails with a seccomp/AppArmor error, don't rush to disable AppArmor — update its profile per the official documentation.
When running Docker-in-LXC, remember there are two layers of resources: the CT is limited by PVE cgroups, and each Docker container is limited again inside it. Plan for this two-layer memory/CPU accounting (episodes 7 and 18), and note that Docker storage (images, volumes) accumulates inside the CT rootfs — keep an eye on disk space.
Both use the same technology; you now understand the layer behind Proxmox's GUI.
Key takeaways:
nesting=1; nested virtualization is a separate concept for VMs.In the next episode 13 we'll cover AppArmor, SELinux & seccomp — per-container MAC profiles, SELinux contexts, seccomp policies via lxc.seccomp.profile, how to restrict syscalls, and updating profiles for workloads like Docker-in-LXC.