Skip to main content

LXC Containers in Proxmox VE: Creation and Management

Proxmox VE · 19.04.2026 · 7 min read
Illustration for “LXC Containers in Proxmox VE: Creation and Management”

LXC containers (Linux Containers) in Proxmox share the host's kernel, which makes them far lighter and faster than full VMs. A container starts in seconds and consumes minimal resources while offering the same level of isolation for most tasks that do not need a separate kernel or a different operating system.

VM vs LXC: when to use which

If the task calls for a full VM, the creation steps are covered in creating a virtual machine in Proxmox VE.

CriterionVM (KVM)LXC container
Startup time30-60 seconds1-3 seconds
RAM consumptionHigher (its own kernel)Lower (shared kernel)
IsolationFull (hardware)Partial (namespaces)
OSAny (Windows, Linux, BSD)Linux only
I/O performanceSmall overheadNear-native
Docker supportFullLimited (needs nesting)

Step 1: download a container template

# Refresh the template list
pveam update

# Show the available templates
pveam available | grep -E "debian|ubuntu|alpine"

# Download a template
pveam download local debian-12-standard_12.7-1_amd64.tar.zst

Or through the web interface: local → CT Templates → Templates, then pick one and download it.

Step 2: create the container

# Create an unprivileged container with ID 200
pct create 200 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
  --hostname mycontainer \
  --rootfs local-lvm:8 \
  --memory 512 --swap 512 --cores 1 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --password SecurePass123 \
  --unprivileged 1 --onboot 1

# Start the container
pct start 200

# Open the console
pct enter 200

Common errors explained

  • unable to create CT 200 - unable to parse value of 'rootfs' - storage 'local-lvm' does not exist — the host uses a different storage backend (ZFS, a directory, and so on); use the real name from pvesm status instead of a value copied from an unrelated example.
  • startup for container '200' failed in the log after pct start — usually an IP conflict or the vmbr0 bridge not being up on the host yet; check ip a and confirm the bridge exists before creating the container.
  • lxc-start: 200: ... Permission denied - Failed to mount — an attempt to mount a device or filesystem inside an unprivileged container that requires root on the host; either lift the restriction for that specific case or switch to a privileged container just for that task.
  • CT is locked (snapshot) when trying to change the configuration — a previous snapshot operation did not finish; the lock can be cleared with pct unlock 200, but only after confirming the operation is truly stuck.

Privileged vs unprivileged containers

Recommendation: always use --unprivileged 1 (the default). Unprivileged containers are safer — processes inside run as UID/GID shifted by 100000, which rules out privilege escalation to the host even if a process inside the container is compromised.

Privileged containers are only needed for specific tasks: working with devices, NFS mounts, and a few networking features that require real root on the host.

Setting up bind mounts

# Mount a host directory into the container
pct set 200 --mp0 /data/shared,mp=/mnt/shared,backup=0

# Mount it through the config file
cat /etc/pve/lxc/200.conf
# mp0: /data/shared,mp=/mnt/shared

Enabling Docker inside LXC

Running Docker inside an LXC container needs extra settings:

# Add to /etc/pve/lxc/200.conf on the Proxmox host
features: keyctl=1,nesting=1

# Restart the container
pct stop 200 && pct start 200

# Install Docker inside the container
curl -fsSL https://get.docker.com | bash

Security: Docker in LXC with nesting=1 reduces isolation. For production workloads, run Docker inside a full VM instead.

Comparing storage options for container rootfs

Details on each storage type are in the article on storage in Proxmox VE.

StorageSnapshotsSpeedWhen to use it
local-lvm (thin)YesHighDefault for most nodes
ZFSYes, instantHighFrequent snapshots and replication needed
DirectoryNoMediumTest environments, simple setup

When LXC does not fit

  • A non-Linux system is needed (Windows, FreeBSD) — LXC shares the kernel with the host and physically cannot run a different OS; that calls for a full VM on KVM.
  • The application needs its own network stack with kernel parameter changes (a custom sysctl set for routing, for example) — the host's shared kernel limits such settings at the container level.
  • Guaranteed hard isolation is required for a multi-tenant environment with untrusted users — LXC namespaces have historically had more escape vulnerabilities than KVM's hardware virtualization.

Useful pct commands

# List containers
pct list

# Container status
pct status 200

# Stop it
pct stop 200

# Snapshot
pct snapshot 200 backup1

# Clone the container
pct clone 200 201 --full --hostname container2

# Delete it
pct destroy 200

How to verify the container works correctly

# The container is running with no config errors
pct status 200
pct config 200

# Networking inside the container came up
pct exec 200 -- ip a
pct exec 200 -- ping -c 3 8.8.8.8

# Real-time resource usage
pct exec 200 -- free -m

If pct status shows running, the container has an IP address and responds to ping, and free -m shows the expected amount of memory, the container is configured and working normally.

Frequently asked questions

Can a running LXC container later be converted into a full VM if the workload outgrows it?

Proxmox has no automatic conversion from a container to a virtual machine: LXC and VM rely on different storage and boot mechanisms. In practice people move the content instead — files, databases, application configuration — into a new VM by hand or through a backup, then stop and remove the original container once the move is done.

Is it safe to run a production database inside an LXC container?

Technically yes, with a caveat: an unprivileged container on a recent host kernel with properly configured storage, such as ZFS or thin LVM, handles a database about as well as a VM. The risk grows when guaranteed hard isolation from other containers on the same host matters — then a dedicated VM or even a physical server makes more sense.

Can you create several containers from the same template without conflicts between them?

Yes, several containers built from the same template coexist without conflict as long as each one gets its own numeric ID, hostname, and network address. A conflict only shows up when two containers end up with the same IP through DHCP or the same hostname on a shared network — an ordinary networking issue, not a limitation of LXC itself.

Can an unprivileged container see the processes and resources of other containers on the same host?

No, namespaces isolate each container's processes and resources from the others: from inside one container you cannot see the neighbor's processes, even when both run on the same host. For an unprivileged container that isolation is reinforced further by the UID/GID shift, which keeps the risk of affecting neighbors low even if something goes wrong inside the container itself.

Was this article helpful?
← Back to Knowledge Base Ask Support