Running Docker on Proxmox VE: Best Practices
Learn the best practices for running Docker on Proxmox VE, including choosing between VMs and LXC containers, setting up Docker Compose, deploying Portainer, and configuring storage drivers for optimal performance.
Docker on Proxmox: VM vs LXC Container
Proxmox VE gives you two ways to run Docker: inside a full virtual machine or inside an LXC container. Both approaches work, but they have different trade-offs that matter depending on your workload.
Running Docker inside a VM is the officially supported and most compatible approach. The VM has its own kernel, so Docker features like overlay filesystems, cgroups, and namespaces work without any limitations. This is the recommended path for production workloads, complex Docker Compose stacks, and anything that requires full kernel control.
Running Docker inside an LXC container is lighter on resources — no separate kernel, faster boot times, and lower memory overhead. However, it requires enabling nesting and may have compatibility issues with certain Docker features. This approach works well for simple containers and development environments.
Option 1: Docker in a VM (Recommended)
Create a Debian or Ubuntu VM with at least 2 CPU cores, 2 GB RAM, and 32 GB of disk space. After installing the OS, install Docker using the official repository:
# Add Docker's official GPG key and repository
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine and Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Add your user to the docker group
sudo usermod -aG docker $USER
Option 2: Docker in an LXC Container
If you prefer the lightweight approach, create a Debian or Ubuntu LXC container in Proxmox and enable nesting. You can do this from the Proxmox shell:
# Create a privileged container with nesting enabled
pct create 110 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
--hostname docker-lxc \
--memory 2048 \
--cores 2 \
--rootfs local-lvm:32 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--features nesting=1 \
--unprivileged 0
# Start the container
pct start 110
Inside the container, install Docker with the same commands as the VM method. The key difference is the nesting=1 feature flag, which allows Docker to create its own namespaces inside the LXC container.
Note: Unprivileged LXC containers can also run Docker with nesting enabled, but some workloads may encounter permission issues. Start with a privileged container if you run into problems, then migrate to unprivileged once things are working.
Setting Up Docker Compose
Docker Compose is the standard way to define multi-container applications. With the Compose plugin installed, you can manage entire application stacks with a single YAML file. Here is an example that runs Nginx with a Redis cache:
# docker-compose.yml
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
depends_on:
- cache
restart: unless-stopped
cache:
image: redis:alpine
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
redis_data:
# Deploy the stack
docker compose up -d
# View running containers
docker compose ps
# View logs
docker compose logs -f web
Deploying Portainer for Web Management
Portainer gives you a web-based GUI to manage Docker containers, images, volumes, and networks. It is especially useful if you prefer not to use the command line for day-to-day container management:
# Create a volume for Portainer data
docker volume create portainer_data
# Deploy Portainer CE
docker run -d \
--name portainer \
--restart=always \
-p 8000:8000 \
-p 9443:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
Access Portainer at https://your-ip:9443 and create your admin account on first login.
Storage Driver Configuration
The storage driver Docker uses affects performance significantly. On Proxmox, your best options depend on the backing filesystem:
- overlay2 on ext4/xfs — The default and recommended driver for most setups. Works reliably in both VMs and LXC containers.
- overlay2 on ZFS — If your Proxmox storage is ZFS, create an ext4-formatted zvol for the VM disk or use a dedicated dataset. Running overlay2 directly on ZFS can cause performance issues.
- zfs driver — Docker has a native ZFS driver, but it is slower for build-heavy workflows due to dataset creation overhead.
Check your current storage driver and verify it is performing well:
# Check current storage driver
docker info | grep "Storage Driver"
# Check disk usage
docker system df
# Clean up unused resources
docker system prune -a --volumes
Monitoring Your Docker Host
Once Docker is running on your Proxmox infrastructure, you will want to keep an eye on resource consumption. Proxmox's web UI shows VM and container-level metrics, but for quick checks from your phone — especially when you are away from your desk — ProxmoxR lets you monitor the host's CPU, memory, and disk usage so you can spot a runaway container before it causes problems.
Running Docker on Proxmox is a powerful combination. Start with a VM for maximum compatibility, use Docker Compose to define your stacks declaratively, and add Portainer if you want a visual management layer. With proper storage configuration and monitoring, your containerized services will run reliably for years.
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.