Introduction
If you’re running a home lab, chances are you’ve heard of Proxmox VE—the powerful, open-source virtualization platform that supports both KVM VMs and LXC containers. It’s a favorite among self-hosters for good reason: it’s fast, flexible, and free.
But here’s the million-dollar question many home labbers run into:
“Can I run Docker inside an LXC container on Proxmox?”
Short answer: Yes.
Long answer: Yes, but with some caveats and a bit of elbow grease.
This blog post dives deep into how to configure an LXC container on Proxmox to run Docker, why you might want to do this instead of using full VMs, and how to avoid common pitfalls. Let’s get you up and running.
🤔 Why Run Docker in an LXC Container?
So, why not just run Docker in a VM?
Here’s why LXC makes sense:
- Performance: LXC containers are more lightweight than full VMs. Less overhead, faster boots, and better density.
- Efficiency: Share the kernel with the host. Great for simple Docker workloads.
- Manageability: Snapshots, backups, and templates are faster with LXC.
However, Docker wasn’t designed for LXC, so some fine-tuning is needed to get them to play nice.
🛠️ Step-by-Step: Running Docker in an LXC Container on Proxmox
1. Prerequisites
- Proxmox VE installed (version 7.x or higher recommended)
- Root SSH or shell access to Proxmox
- Basic knowledge of Proxmox and Docker
2. Create a Docker-Friendly LXC Template
Let’s start by creating an LXC container that can support Docker.
Option A: Use TurnKey or Ubuntu 22.04 Template
# Download Ubuntu template
pveam update
pveam available | grep ubuntu
pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.zst
3. Create the LXC Container
You can create it via GUI or CLI. Let’s use CLI for better control.
pct create 105 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
-hostname docker-lxc \
-storage local-lvm \
-rootfs 8G \
-memory 2048 \
-cores 2 \
-net0 name=eth0,bridge=vmbr0,ip=dhcp \
-features nesting=1,keyctl=1 \
-unprivileged 1
Important flags:
nesting=1
: Required to run Dockerkeyctl=1
: Required for container secrets and some Docker imagesunprivileged=1
: More secure, but needs extra steps for Docker
4. Configure the Container (Post-Creation)
After creating the container:
pct start 105
pct exec 105 -- bash
Now, inside the container:
# Update and install dependencies
apt update && apt upgrade -y
apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# Add Docker repo
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
apt update
apt install -y docker-ce docker-ce-cli containerd.io
✅ Docker is now installed inside your LXC container.
Check it:
docker run hello-world
5. Fix CGroup and OverlayFS Issues (If Any)
Sometimes Docker won’t work out-of-the-box with unprivileged LXC. Fixes include:
Enable CGroup v1 Compatibility
Edit the LXC config file on Proxmox:
nano /etc/pve/lxc/105.conf
Add or modify:
lxc.apparmor.profile: unconfined
lxc.cgroup.devices.allow: a
lxc.cap.drop:
Then reboot the container:
pct restart 105
⚠️ Unprivileged containers may need UID mapping and subuid/subgid entries. For most home lab uses, the config above is sufficient.
📦 Real-World Use Cases
So now that Docker is running inside an LXC container, what can you do?
✅ Host lightweight apps
Spin up your favorite self-hosted tools:
# Example docker-compose
version: '3.3'
services:
uptime-kuma:
image: louislam/uptime-kuma
container_name: uptime-kuma
volumes:
- ./data:/app/data
ports:
- 3001:3001
restart: unless-stopped
✅ Use with Portainer
Install Portainer inside your LXC container to manage your Docker environment via GUI:
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce
✅ Use as Dev Environments
Isolate different environments using LXC + Docker stacks (e.g., a full Node.js or Python dev stack).
🧯 Common Issues and Fixes
Problem | Fix |
---|---|
docker: failed to start shim |
Ensure nesting=1 and keyctl=1 are enabled |
Docker requires overlay2 but fails |
Use privileged container or adjust storage backend |
Can’t use Docker volumes | Check mount permissions and UID mappings |
Network issues | Make sure container has bridged network and proper DNS |
Docker daemon won’t start | Check logs: journalctl -u docker.service inside LXC |
🧠 Final Thoughts
Running Docker inside LXC on Proxmox isn’t always plug-and-play, but with the right configuration, it’s a powerful and resource-efficient setup for your home lab.
If you’re trying to maximize your Proxmox node’s efficiency while keeping workloads isolated and manageable, this is the way.
🙌 Call to Action
Have you tried this setup? Gotchas to share?
Drop your feedback, questions, or tips in the comments or reach out on GitHub 👉 github.com/tabishshaikh90
And if you liked this post, follow my blog for more home lab guides and automation tips!
📚 Resources:
Happy Homelabbing!
— Tabish Shaikh