Proxmox LXC Containers: Tiny Linux Servers Without the VM Weight

I use Proxmox mainly because it gives me a very nice playground for VMs, containers, storage tests and the occasional “why is this not booting anymore?” evening session.

One feature that is easy to overlook at first is LXC containers.

When people hear “container”, they often immediately think of Docker. But Proxmox LXC containers are a bit different. They feel more like tiny Linux servers than application containers. You get a root filesystem, a hostname, network config, resource limits and a console. Basically a small Linux system without the full VM overhead. And that is pretty useful in a homelab.

What is an LXC container?

An LXC container is an operating-system-level container.

That means it does not emulate virtual hardware like a full VM. Instead, it shares the Linux kernel of the Proxmox host and uses Linux features like namespaces, cgroups and AppArmor for isolation. This makes LXC containers very lightweight. They start quickly, use fewer resources and are perfect for many small Linux services.

LXC vs VM in Proxmox

In Proxmox you normally have two main options:

OptionBest for
VM / KVMFull isolation, different operating systems, Windows, Docker hosts, kernel-level testing
LXCLightweight Linux services, small tools, internal apps, quick test systems

I usually think about it like this:

  • Use a VM when I need strong isolation or a full operating system.
  • Use an LXC container when I just need a lightweight Linux box to run a service.

Good LXC candidates:

  • Pi-hole / AdGuard
  • small web server
  • monitoring tools
  • reverse proxy
  • lightweight database test system
  • internal scripts
  • tiny Debian/Ubuntu utility box etc.

Better as VM:

  • Windows Server ( it’s called Linux Containers for a reason )
  • Docker host with many containers
  • Kubernetes nodes
  • untrusted workloads
  • anything where kernel isolation really matters

LXC is great, but it is not magic security dust. All containers still share the host kernel. So do not treat it like a full VM if you are running something sketchy from the dark corners of GitHub at 1 AM.

Create your first LXC container

In the Proxmox GUI, the process is pretty simple.

Go to:

Node → local storage → CT Templates

Then click Templates and download a Linux template, for example Debian or Ubuntu.

After that click Create CT in the top right corner.

Typical settings:

  • CT ID: 101
  • Hostname: web01
  • Template: Debian or Ubuntu template
  • Disk: 8 GB or more
  • CPU: 1–2 cores
  • Memory: 1024–2048 MB
  • Network: vmbr0
  • IP: DHCP for testing, static for production-like services
  • Unprivileged container: yes, if possible

For most homelab services I would start with an unprivileged container. Only use privileged containers when you actually need them.

Create an LXC container from the CLI / Proxmox Shell

First update the template list:

pveam update

Search eg. for a Debian template:

pveam available | grep debian

Download the template:

pveam download local debian-12-standard_<version>_amd64.tar.zst

Then create the container:

pct create 101 local:vztmpl/debian-12-standard_<version>_amd64.tar.zst \
--hostname web01 \
--rootfs local-lvm:8 \
--cores 2 \
--memory 2048 \
--swap 512 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 1

Replace the template name with the actual file you downloaded.

Start and access the container

Start it:

pct start 101

Open a shell inside it:

pct enter 101

Or use:

pct console 101

Check the container status:

pct status 101

List all containers:

pct list

At this point you basically have a small Linux server and you can install whatever service you want. Don’t forget to update it!

Set a static IP address

For quick tests DHCP is fine, for real services, I prefer static IPs.

Example:

pct set 101 --net0 name=eth0,bridge=vmbr0,ip=192.168.10.50/24,gw=192.168.10.1

Then restart the container:

pct restart 101

Inside the container, check:

ip a
ip r

If DNS is broken, check:

cat /etc/resolv.conf

Change CPU and memory

One nice thing about LXC containers is that resource changes are easy.

Set memory to 2 GB:

pct set 101 --memory 2048

Set swap to 512 MB:

pct set 101 --swap 512

Set CPU cores:

pct set 101 --cores 2

Check the config:

pct config 101

You can also view the config file directly on the Proxmox host:

cat /etc/pve/lxc/101.conf

You can edit this file directly, but I recommend changing settings through the Proxmox GUI or pct whenever possible. It reduces the risk of syntax or configuration mistakes.

Resize the container disk

If the container runs out of space, you can extend the root disk.

Add 10 GB:

pct resize 101 rootfs +10G

Check inside the container:

df -h

Usually this is picked up automatically for LXC containers.

Shrinking disks is a different story and should not be treated as a casual “let me just make this smaller” operation. Make a backup first. Actually, make two if this is important.

Add a bind mount

Sometimes you want the container to access a directory from the Proxmox host.

Example:

pct set 101 -mp0 /mnt/pve/data/appdata,mp=/mnt/appdata

This mounts the host path:

/mnt/pve/data/appdata

inside the container as:

/mnt/appdata

This is useful for app data, shared folders or media directories.

But be careful: Bind mounts are also a nice way to accidentally expose host data to a container. Do not mount half your host filesystem into a random container and then act surprised when permissions become spicy.

Snapshots and backups

Snapshots are useful before updates.

In the GUI:

Container → Snapshots → Take Snapshot

From CLI:

pct snapshot 101 before-upgrade

Rollback:

pct rollback 101 before-upgrade

But snapshots are not backups! Snapshots help when you break something locally.

Backups help when your storage breaks, your node dies, or you delete the wrong thing while being “almost sure” this was the test container.

For a proper backup you can use Proxmox vzdump:

vzdump 101 --mode snapshot --storage <backup-storage> --compress zstd

If you use Proxmox Backup Server, even better. PBS is one of the best things in the Proxmox ecosystem and feels like it was designed by people who have also accidentally destroyed things before.

Restore an LXC backup

A container backup can be restored with:

pct restore 102 /path/to/vzdump-lxc-101.tar.zst --storage local-lvm

This restores the backup as container ID 102.

I like restoring to a new ID first when testing. That way the original container stays untouched.

Because “just restoring over production” is how a calm evening turns into a learning experience.

Migrate an LXC container

In a Proxmox cluster, containers can be migrated to another node.

From the GUI:

Right click container → Migrate

From CLI:

pct migrate 101 target-node

Depending on your storage and configuration, the container may need to be stopped or restarted during migration.

So do not assume every LXC migration is magically live and invisible. Test it before relying on it.

My usual LXC best practices

For my own setup, I would keep it simple:

  • Use unprivileged containers by default.
  • Use static IPs for important services.
  • Keep containers small and focused.
  • Do not put every service into one giant container.
  • Use bind mounts carefully.
  • Back up containers before major changes.
  • Prefer VMs for Docker-heavy workloads.
  • Document the container ID, IP and purpose.

Example naming:

101-dns01
102-nginx01
103-monitoring01
104-test-debian

Future-you will be thankful.

My Verdict

LXC containers are one of those Proxmox features that sounds a bit boring at first, but becomes surprisingly useful once you actually start using it. And honestly, boring infrastructure is usually the best kind of infrastructure.

They are fast, lightweight and perfect for small Linux-based services in a homelab. Not every service needs a full VM with virtual hardware, its own kernel and a dramatic boot sequence. Sometimes you just need a clean little Linux container that starts quickly, does its job and stays out of the way.

For me, the rule is simple: use LXC for small, trusted Linux services — and use VMs when things get complex, exposed or messy.