Skip to main content
Docker is essential for running containerized applications. This guide covers multiple methods for running Docker on Proxmox VE.

Installation Methods

Alpine Docker LXC

Lightweight Container
  • Minimal resource usage
  • Fast deployment
  • Best for: Simple Docker workloads

Docker VM

Full Virtual Machine
  • Complete isolation
  • Multiple OS options
  • Best for: Production environments

Alpine Docker Container (LXC)

Quick Installation

1

Run the Alpine Docker Script

bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/alpine-docker.sh)"
2

Container Configuration

Default settings:
  • CPU: 1 core
  • RAM: 1024 MB
  • Disk: 2 GB
  • OS: Alpine 3.23
  • Unprivileged: Yes
3

Verify Installation

pct enter <CTID>
docker --version
docker ps

Why Alpine?

Lightweight

Base container ~50 MB vs 300+ MB for Ubuntu

Secure

Minimal attack surface with fewer packages

Fast

Quick startup and low resource usage

Docker VM (Full Installation)

For production workloads, a full VM provides better isolation and flexibility.

Quick Installation

1

Run the Docker VM Script

bash -c "$(wget -qO - https://github.com/community-scripts/ProxmoxVE/raw/main/vm/docker-vm.sh)"
2

Choose Operating System

Select from:
  • Debian 13 (Trixie) - Latest
  • Debian 12 (Bookworm) - Stable (recommended)
  • Ubuntu 24.04 LTS - Long-term support
  • Ubuntu 22.04 LTS - Older LTS
3

Cloud-Init Configuration

Enable Cloud-Init for:
  • Automatic user setup
  • SSH key injection
  • Network configuration
  • First-boot customization
4

Wait for Installation

The script will:
  • Download OS image
  • Pre-install Docker
  • Configure networking
  • Start the VM

Default VM Configuration

SettingDefault Value
VM IDNext available
Machine TypeQ35 (Modern)
Disk Size10 GB
Hostnamedocker
CPU ModelHost
CPU Cores2
RAM4096 MB
Networkvmbr0
The Docker VM script pre-installs Docker during image creation, so it’s ready immediately after first boot.

Docker Configuration

Optimized Daemon Settings

The scripts automatically configure Docker with optimized settings:
{
  "storage-driver": "overlay2",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
Configuration location: /etc/docker/daemon.json
overlay2 is the recommended storage driver for performance and stability.

Verify Docker Installation

# Enter the container
pct enter <CTID>

# Check Docker version
docker --version

# Test with hello-world
docker run hello-world

Running Docker Containers

Basic Container Management

1

Pull an Image

docker pull nginx:latest
2

Run a Container

docker run -d -p 80:80 --name webserver nginx:latest
3

View Running Containers

docker ps
4

View Logs

docker logs webserver

Docker Compose

Docker Compose is pre-installed in VMs. For Alpine containers:
# Install Docker Compose (Alpine)
apk add docker-compose
Example docker-compose.yml:
version: '3.8'
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    restart: unless-stopped
    
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: changeme
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:
Run with:
docker-compose up -d

Storage Configuration

Persistent Volumes

For data persistence, use Docker volumes:
# Create a volume
docker volume create mydata

# Use in container
docker run -v mydata:/data nginx:alpine

# List volumes
docker volume ls

Bind Mounts

Mount host directories:
# Create directory
mkdir -p /opt/appdata

# Mount in container
docker run -v /opt/appdata:/data nginx:alpine
For LXC containers, ensure the directory permissions match between host and container.

Increasing Disk Space

# Resize container disk
pct resize <CTID> rootfs +10G

Networking

Container Networking

Bridge Network

Default Docker network
docker network create mynetwork

Host Network

Use host’s network stack
docker run --network host nginx

Port Mapping

# Map container port to host
docker run -p 8080:80 nginx

# Map to specific interface
docker run -p 192.168.1.100:8080:80 nginx

# Map multiple ports
docker run -p 80:80 -p 443:443 nginx

Macvlan Network

For containers to appear as separate devices on network:
# Create macvlan network
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 macvlan_net

# Run container on macvlan
docker run --network macvlan_net \
  --ip=192.168.1.100 nginx

Docker Management Tools

Portainer

Web-based Docker management:
docker run -d \
  -p 9000:9000 \
  --name portainer \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest
Access at: http://<ip>:9000

Dockge

Docker Compose management UI:
# Or use the community script
bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/tools/addon/dockge.sh)"

Yacht

Container management for beginners:
docker run -d \
  -p 8001:8000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v yacht:/config \
  selfhostedpro/yacht

Performance Optimization

CPU Limits

Limit CPU usage:
# Limit to 50% of one core
docker run --cpus="0.5" nginx

# Limit to specific cores
docker run --cpuset-cpus="0,1" nginx

Memory Limits

# Set memory limit
docker run -m 512m nginx

# Set memory + swap limit
docker run -m 512m --memory-swap 1g nginx

Storage Optimization

1

Clean Unused Images

docker image prune -a
2

Clean Unused Volumes

docker volume prune
3

Clean Everything

docker system prune -a --volumes
Pruning removes all unused containers, images, and volumes. Ensure you have backups.

Security Best Practices

Use Unprivileged Containers

# Run as non-root user
docker run --user 1000:1000 nginx

Read-Only Filesystem

# Mount root as read-only
docker run --read-only nginx

Limit Capabilities

# Drop all capabilities
docker run --cap-drop=ALL nginx

Use Secrets

# Use Docker secrets
echo "mypassword" | docker secret create db_pass -

Rootless Docker

For enhanced security, run Docker without root:
# Install rootless Docker
curl -fsSL https://get.docker.com/rootless | sh

# Enable at boot
systemctl --user enable docker

Backup and Restore

Backup Containers

# Save container as image
docker commit mycontainer mybackup:latest

# Export image
docker save -o backup.tar mybackup:latest

Restore from Backup

# Load image
docker load -i backup.tar

# Restore volume
docker run --rm \
  -v myvolume:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/volume-backup.tar.gz -C /

Proxmox-Level Backup

Always backup the entire container/VM for complete restoration:
vzdump <CTID> --mode snapshot --compress zstd

Troubleshooting

Check service status:
systemctl status docker
journalctl -u docker -n 50
Restart Docker:
systemctl restart docker
Add user to docker group:
usermod -aG docker $USER
Or use sudo:
sudo docker ps
Check Docker disk usage:
docker system df
Clean up:
docker system prune -a
Resize container/VM disk
Restart networking:
systemctl restart docker
Check iptables:
iptables -L DOCKER

Advanced Topics

Docker Swarm

For container orchestration:
# Initialize swarm
docker swarm init

# Deploy stack
docker stack deploy -c docker-compose.yml mystack

Custom Docker Registry

Run a private registry:
docker run -d -p 5000:5000 \
  --restart unless-stopped \
  --name registry \
  -v registry-data:/var/lib/registry \
  registry:2

Docker BuildKit

Enable BuildKit for faster builds:
export DOCKER_BUILDKIT=1
docker build -t myapp .

Next Steps

Popular Apps

Explore pre-configured applications

Networking

Advanced network configuration

Security

Harden your Docker setup

Build docs developers (and LLMs) love