LXC Containers in Proxmox: Complete Guide
Everything about LXC containers in Proxmox VE. Learn when to use containers vs VMs, how to create them, and best practices.
What Are LXC Containers?
LXC (Linux Containers) is an operating-system-level virtualization technology that allows you to run multiple isolated Linux environments on a single host, all sharing the same kernel. Unlike a full virtual machine which emulates an entire computer with its own kernel, an LXC container is essentially a process group with its own filesystem, network stack, and process tree — but it uses the host's Linux kernel directly.
In Proxmox VE, LXC containers are first-class citizens alongside KVM virtual machines. You create, manage, snapshot, backup, and migrate containers using the same tools and interfaces as VMs. The key difference is that containers use a fraction of the resources, start in seconds, and can run at near-native performance — making them ideal for lightweight Linux services.
LXC vs KVM: When to Use Each
Choosing between containers and VMs is one of the most important decisions you will make when planning your Proxmox infrastructure. Here is a practical comparison:
| Factor | LXC Container | KVM Virtual Machine |
|---|---|---|
| Startup time | 1-3 seconds | 15-60 seconds |
| Memory overhead | Minimal (shares host kernel) | Higher (full OS + kernel) |
| Isolation | Process-level (good, not perfect) | Hardware-level (strong) |
| OS support | Linux only | Any OS (Windows, BSD, etc.) |
| Performance | Near-native | Near-native with virtio |
| GPU passthrough | Limited | Full support |
| Custom kernel | Not possible (shares host) | Full control |
Use LXC when: you are running standard Linux services — web servers, databases, DNS, file sharing, monitoring tools, development environments. Containers excel at these workloads because they need minimal overhead.
Use KVM when: you need Windows, need full hardware isolation (multi-tenant environments), require a specific kernel version, or need features like GPU passthrough.
Downloading Container Templates
Before creating a container, you need a template. Proxmox provides a built-in template browser with images from all major distributions:
# List available templates
pveam available --section system
# Download a template (stored on your selected storage)
pveam download local debian-12-standard_12.2-1_amd64.tar.zst
pveam download local ubuntu-24.04-standard_24.04-2_amd64.tar.zst
pveam download local alpine-3.20-default_20240908_amd64.tar.xz
You can also download templates through the web UI: go to your storage > CT Templates > Templates, then select and download the image you need.
Creating a Container
Create a container using the web UI (Create CT button) or from the command line with pct create:
# Create a basic Debian container
pct create 200 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
--hostname pihole \
--memory 512 \
--swap 256 \
--cores 1 \
--rootfs local-lvm:8 \
--net0 name=eth0,bridge=vmbr0,ip=10.0.0.50/24,gw=10.0.0.1 \
--nameserver 1.1.1.1 \
--password \
--unprivileged 1 \
--start 1
This creates an unprivileged Debian 12 container with 512 MB of RAM, 1 CPU core, 8 GB of disk space, and a static IP address — then starts it immediately.
Privileged vs Unprivileged Containers
This distinction is critical for container security:
Unprivileged Containers (Recommended)
Unprivileged containers map the container's root user (UID 0) to a high-numbered UID on the host (e.g., 100000). This means even if an attacker escapes the container, they have no privileges on the host system. Always use unprivileged containers unless you have a specific reason not to.
Privileged Containers
Privileged containers run with UID 0 mapped directly to UID 0 on the host. They have more access to host resources and are needed for some workloads that require direct access to system devices, NFS mounts, or certain kernel features. However, they carry a higher security risk. Only use privileged containers when unprivileged containers genuinely cannot meet your needs.
# Check if a container is unprivileged
pct config 200 | grep unprivileged
# unprivileged: 1 (yes) or 0/missing (no)
Resource Limits and Configuration
One of the advantages of LXC containers is granular resource control:
# Adjust CPU cores and memory
pct set 200 --cores 2 --memory 1024 --swap 512
# Resize the root filesystem (increase only)
pct resize 200 rootfs 16G
# Add CPU limits (percentage of a core, e.g., 50% of one core)
pct set 200 --cpulimit 0.5
# Set CPU units for relative priority (default 1024)
pct set 200 --cpuunits 2048
Many of these changes can be applied without restarting the container, which is a significant advantage over VMs.
Bind Mounts: Sharing Host Directories
Bind mounts let you expose a directory from the Proxmox host (or an NFS mount) directly inside a container. This is extremely useful for shared data, media libraries, and backups:
# Add a bind mount to an existing container (must be stopped)
pct set 200 --mp0 /mnt/data/media,mp=/media,ro=0
# In the container config file (/etc/pve/lxc/200.conf):
mp0: /mnt/data/media,mp=/media
For unprivileged containers, you may need to handle UID/GID mapping to ensure the container can read and write to the mounted directory:
# Map host UID 1000 to container UID 1000
# Add to /etc/pve/lxc/200.conf:
lxc.idmap: u 0 100000 1000
lxc.idmap: u 1000 1000 1
lxc.idmap: u 1001 101001 64535
lxc.idmap: g 0 100000 1000
lxc.idmap: g 1000 1000 1
lxc.idmap: g 1001 101001 64535
Nesting: Running Docker Inside LXC
A common question is whether you can run Docker inside an LXC container. The answer is yes, with the nesting feature enabled:
# Enable nesting and keyctl (required for Docker)
pct set 200 --features nesting=1,keyctl=1
After enabling nesting, you can install and run Docker inside the container normally. This gives you the lightweight footprint of LXC with the application packaging convenience of Docker. Note that nesting works best with unprivileged containers running a recent kernel.
Common LXC Service Deployments
Here are some of the most popular services to run inside Proxmox LXC containers:
Pi-hole DNS
# Inside an unprivileged Debian/Ubuntu container:
curl -sSL https://install.pi-hole.net | bash
A Pi-hole container needs just 256 MB of RAM and one CPU core. It is one of the most efficient ways to run network-wide ad blocking.
Nginx Reverse Proxy
apt update && apt install -y nginx certbot python3-certbot-nginx
systemctl enable nginx
Run your reverse proxy in a dedicated lightweight container rather than on the Proxmox host itself.
PostgreSQL Database
apt update && apt install -y postgresql
systemctl enable postgresql
su - postgres -c "createuser --interactive"
Databases run exceptionally well in LXC containers because there is zero virtualization overhead on disk I/O.
Container Management Commands
# Start, stop, restart
pct start 200
pct stop 200
pct reboot 200
# Enter the container shell
pct enter 200
# Execute a command inside the container
pct exec 200 -- apt update
# Create a snapshot
pct snapshot 200 before-upgrade --description "Before package upgrade"
# List snapshots
pct listsnapshot 200
# Rollback to a snapshot
pct rollback 200 before-upgrade
# Clone a container
pct clone 200 201 --hostname pihole-backup --full
When managing a server with many containers, being able to quickly check container status and perform basic operations remotely is valuable. ProxmoxR gives you a mobile-friendly overview of all your LXC containers alongside your VMs — you can see which containers are running, check their resource usage, and start or stop them without needing to SSH into your server.
Best Practices
- Default to unprivileged: Only use privileged containers when you have a documented reason.
- Right-size resources: Start with minimal resources and scale up based on actual usage. Containers make this easy since many changes are live.
- One service per container: Follow the principle of running one primary service per container for easier maintenance, updates, and troubleshooting.
- Use Alpine for minimal footprint: Alpine Linux containers use as little as 8 MB of RAM at idle — perfect for lightweight services.
- Snapshot before updates: Always take a snapshot before running package upgrades so you can roll back if something breaks.
- Use templates: Configure a base container the way you want it, then convert it to a template for cloning new containers quickly.
Summary
LXC containers in Proxmox VE offer a lightweight, efficient alternative to full virtual machines for Linux-based workloads. They start in seconds, use minimal resources, and run at near-native performance — making them perfect for services like DNS, web servers, databases, and development environments. By understanding the differences between privileged and unprivileged containers, using bind mounts effectively, and following security best practices, you can run dozens of services on modest hardware while keeping your infrastructure clean and maintainable.
Take Proxmox management mobile
All the features discussed in this guide — accessible from your phone with ProxmoxR. Real-time monitoring, power control, firewall management, and more.