Files
2025-11-30 08:47:38 +08:00

4.8 KiB

Docker on Proxmox VMs

Best practices for running Docker workloads on Proxmox VE.

Template Selection

Use Docker-ready templates (102+) which have Docker pre-installed:

Template ID Name Docker?
100 tmpl-ubuntu-2404-base No
101 tmpl-ubuntu-2404-standard No
102 tmpl-ubuntu-2404-docker Yes
103 tmpl-ubuntu-2404-github-runner Yes
104 tmpl-ubuntu-2404-pihole Yes

DO NOT install Docker via cloud-init on templates 102+.

VM vs LXC for Docker

Factor VM (QEMU) LXC Unprivileged LXC Privileged
Docker support Full Limited Works but risky
Isolation Complete Shared kernel Shared kernel
Overhead Higher Lower Lower
Nested containers Works Requires config Works
GPU passthrough Yes Limited Limited
Security Best Good Avoid

Recommendation: Use VMs for Docker workloads. LXC adds complexity for marginal resource savings.

VM Sizing for Docker

Minimum for Docker host

CPU: 2 cores
RAM: 4 GB (2 GB for OS, 2 GB for containers)
Disk: 50 GB (20 GB OS, 30 GB images/volumes)

Per-container overhead

Base: ~10 MB RAM per container
Image layers: Shared between containers
Volumes: Depends on data

Sizing formula

Total RAM = 2 GB (OS) + sum(container memory limits) + 20% buffer
Total Disk = 20 GB (OS) + images + volumes + 20% buffer

Storage Backend Selection

Proxmox Storage Docker Use Case Performance
local-lvm General workloads Good
ZFS Database containers Better (snapshots)
Ceph HA workloads Good (distributed)
NFS Shared config/data Moderate

Volume mapping to Proxmox storage

# docker-compose.yaml
volumes:
  db_data:
    driver: local
    driver_opts:
      type: none
      device: /mnt/storage/mysql  # Map to Proxmox storage mount
      o: bind

Network Considerations

Bridge mode (default)

Container gets private IP, NAT to VM IP. Good for most workloads.

services:
  web:
    ports:
      - "80:80"  # VM_IP:80 -> container:80

Host mode

Container shares VM network stack. Use for network tools or performance.

services:
  pihole:
    network_mode: host  # Container uses VM's IPs directly

Macvlan (direct LAN access)

Container gets own IP on Proxmox bridge.

# On Docker host (VM)
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  lan
services:
  app:
    networks:
      lan:
        ipv4_address: 192.168.1.50

networks:
  lan:
    external: true

Note: Requires Proxmox bridge without VLAN tagging on that interface, or pass-through the VLAN-tagged interface to VM.

Resource Limits

Always set limits to prevent container runaway affecting VM:

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

GPU Passthrough

For containers needing GPU (AI/ML, transcoding):

  1. Proxmox: Pass GPU to VM

    hostpci0: 0000:01:00.0,pcie=1
    
  2. VM: Install NVIDIA drivers + nvidia-container-toolkit

  3. Compose:

    services:
      plex:
        deploy:
          resources:
            reservations:
              devices:
                - driver: nvidia
                  count: 1
                  capabilities: [gpu]
    

Backup Considerations

What to backup

Data Method Location
VM disk Proxmox vzdump Includes everything
Docker volumes docker run --volumes-from Application-level
Compose files Git Version control

Proxmox backup includes Docker

When backing up the VM with vzdump, all Docker data (images, volumes, containers) is included.

vzdump <vmid> --mode snapshot --storage backup

Application-consistent backups

For databases, use pre/post scripts:

# Pre-backup: flush and lock
docker exec mysql mysql -e "FLUSH TABLES WITH READ LOCK;"

# vzdump runs...

# Post-backup: unlock
docker exec mysql mysql -e "UNLOCK TABLES;"

Troubleshooting

Container can't reach internet

  1. Check VM can reach internet: ping 8.8.8.8
  2. Check Docker DNS: docker run --rm alpine nslookup google.com
  3. Check iptables forwarding: sysctl net.ipv4.ip_forward

Port not accessible from LAN

  1. Check Proxmox firewall allows port
  2. Check VM firewall (ufw/iptables)
  3. Check container is bound to 0.0.0.0 not 127.0.0.1

Disk space issues

# Check Docker disk usage
docker system df

# Clean up
docker system prune -a --volumes  # WARNING: removes all unused data

# Check VM disk
df -h