Featured image of post Proxmox LXC Containers: Complete Management Guide Featured image of post Proxmox LXC Containers: Complete Management Guide

Proxmox LXC Containers: Complete Management Guide

Complete guide to LXC containers on Proxmox VE. Learn template management, unprivileged vs privileged containers, resource limits, bind mounts, backups, and networking.

What is LXC?

LXC (Linux Containers) is an OS-level virtualization method that runs multiple isolated Linux systems on a single host using a shared kernel. Unlike full virtual machines, LXC containers share the host OS kernel while maintaining their own filesystem, processes, and network stack. This design makes them extremely lightweight and fast to start.

LXC vs Virtual Machines

The choice between LXC containers and VMs depends on your isolation and performance requirements:

FeatureLXC ContainerVM (KVM/QEMU)
Startup timeMilliseconds to secondsSeconds to minutes
Memory overheadMinimal (only app memory)Full OS memory per guest
Disk space100 MB–1 GB2–10+ GB
KernelShares host kernelIndependent kernel
IsolationProcess-levelHardware-level
Best forWeb servers, microservices, dev environmentsMulti-tenant, different OS kernels, full isolation

Downloading Templates

Proxmox provides pre-built container templates via pveam. To list available templates from TurnKey Linux and others:

pveam update
pveam available --section turnkeylinux

Download a template to your local storage:

pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.zst

Creating a Container

Create a container from the CLI or web UI. The essential parameters include hostname, password, storage volume, and network configuration:

pct create 100 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
  --hostname web01 \
  --password securePass123 \
  --storage local-lvm \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --unprivileged 1
pct start 100

Key flags control root password, SSH keys, DNS servers, and CPU/memory allocation.

Unprivileged vs Privileged Containers

Unprivileged containers run with UID/GID mapping via subuid and subgid ranges, mapping root (UID 0) inside the container to a high-numbered unprivileged UID on the host. This prevents container root from having host root access:

# Default mapping: container UID 0 maps to host UID 100000
# /etc/subuid contains: root:100000:65536

Privileged containers run as real root on the host. They offer better filesystem compatibility but lower security.

Key trade-off: Unprivileged containers cannot mount most filesystems (NFS, fuse, bind mounts of host directories) because the kernel blocks unprivileged mounts. If you need NFS mounts or FUSE inside a container, use a privileged container and restrict access with AppArmor.

Resource Limits

Proxmox uses cgroups to enforce resource limits on containers:

ResourceParameterExample
CPU quotacpulimit50 (50% of one core)
CPU corescores4
Memorymemory2048 (MB)
Swapswap512 (MB)
Disk IOPSbwlimit100 (MB/s)

Set limits at creation or via pct set:

pct set 100 --memory 2048 --swap 512 --cpulimit 50 --cores 2

Bind Mounts

Bind mounts share host directories with a container. For unprivileged containers, you must map the UID/GID correctly using the map option:

pct set 100 --mp0 /mnt/storage/data,mp=/srv/data,acl=1

Add the mount point entry in /etc/pve/lxc/100.conf if you need root squash mapping:

mp0: /mnt/storage/data,mp=/srv/data,rootuid=1000,rootgid=1000

For privileged containers, bind mounts work without UID remapping, making them simpler for shared storage.

Snapshots and Cloning

Snapshots capture the container state at a point in time with minimal space overhead (COW):

pct snapshot 100 pre-upgrade --description "Before PHP 8.3 upgrade"

List and rollback snapshots:

pct listsnapshot 100
pct rollback 100 pre-upgrade

Clone a container from a template or snapshot for testing:

pct clone 100 101 --hostname staging-web

Networking Modes

Containers support three network models:

  • Bridged (vmbr) — Container appears as a device on the physical network, gets its own MAC and IP via DHCP. Default and most common.
  • Routed — Container uses a virtual network behind the host, with iptables forwarding. Useful when you control the upstream routing.
  • NAT — Container gets a private IP behind the host, masqueraded to the physical network. Simple but no inbound access without port forwarding.

Backup and Restore

Use vzdump for consistent container backups with quiescing:

vzdump 100 --mode suspend --compress zstd --storage backup-store

To restore a container from backup:

pct restore 200 /var/lib/vz/dump/vzdump-lxc-100-2024_05_22-00_00_00.tar.zst \
  --storage local-lvm

Practical Use Cases

  • Web server — Lightweight Nginx/Apache containers, each isolated per site.
  • Database — MySQL/PostgreSQL in containers with bind-mount to ZFS datasets for snapshots.
  • Docker-in-LXC — Works in privileged containers with nesting=1. Not recommended for production due to Docker’s own isolation model conflicting with LXC cgroups.