How to Run Docker Inside an LXC Container on Proxmox: A Practical Home Lab Guide

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 Docker
  • keyctl=1: Required for container secrets and some Docker images
  • unprivileged=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

Leave a Reply

Your email address will not be published. Required fields are marked *