Skip to content
advanced Phase 3 · Docker Volumes & Storage

Storage Drivers

Understand overlay2, aufs, and other Docker storage drivers.

45m
0 problems
Topic Progress 0%

Storage Driver Overview

Storage Driver Overview

Docker storage drivers implement the union filesystem (UnionFS) — a mechanism that creates a unified view of multiple directories (layers) as a single filesystem.

How It Works

┌─────────────────────────────────┐
│      Container (writable)       │ ← Thin writable layer
├─────────────────────────────────┤
│      Image Layer 3              │ ← RUN npm install
├─────────────────────────────────┤
│      Image Layer 2              │ ← COPY . .
├─────────────────────────────────┤
│      Image Layer 1              │ ← FROM node:20
├─────────────────────────────────┤
│      Base OS                    │ ← Host filesystem
└─────────────────────────────────┘

When a container reads a file:

  1. Check the writable layer — if found, return it
  2. Check image layers top-to-bottom — return the first match
  3. If not found, return file not found

When a container writes a file (copy-on-write):

  1. The file is copied from the read-only layer to the writable layer
  2. The modification is applied to the writable copy
  3. The read-only layer remains unchanged

Supported Storage Drivers

Driver Description Best For
overlay2 Modern overlay filesystem Most Linux systems (recommended)
btrfs Btrfs copy-on-write Btrfs filesystem
zfs ZFS on Linux ZFS filesystem
devicemapper Device mapper thin provisioning Legacy systems
vfs No CoW (copy everything) Testing only

Check Current Driver

$ docker info | grep "Storage Driver"
 Storage Driver: overlay2

# See driver details
$ docker info | grep -A 5 "Storage Driver"
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false

overlay2 Deep Dive

overlay2 Deep Dive

overlay2 is the recommended storage driver for most Linux distributions. It's efficient, well-tested, and supports modern kernel features.

How overlay2 Works

overlay2 uses two directories:

  • lowerdir: Read-only image layers
  • upperdir: Writable container layer
  • merged: The unified view presented to the container
# View overlay2 directory structure
ls /var/lib/docker/overlay2/
# a1b2c3d4e5f6.../  (layer directories)

# Inside a layer directory
cd /var/lib/docker/overlay2/a1b2c3d4e5f6.../
ls
# diff/  link  lower  work/

Container Filesystem Structure

# View mount information for a container
docker inspect --format '{{json .GraphDriver}}' web | python3 -m json.tool

# Output:
{
  "Data": {
    "LowerDir": "/var/lib/docker/overlay2/layer1/diff:...",
    "MergedDir": "/var/lib/docker/overlay2/merged",
    "UpperDir": "/var/lib/docker/overlay2/writable/diff",
    "WorkDir": "/var/lib/docker/overlay2/writable/work"
  },
  "Name": "overlay2"
}

Requirements

# Check kernel version (need 4.0+ for overlay2)
uname -r
# 6.5.0-44-generic

# Check filesystem supports d_type
docker info | grep "Supports d_type"
# Supports d_type: true

# If d_type not supported:
# Error: overlay2 is not supported over xfs with ftype=0
# Fix: Remount with ftype=1 or use ext4

Performance Optimization

# Use fast storage (SSD/NVMe) for Docker data root
docker info | grep "Docker Root Dir"
# Docker Root Dir: /var/lib/docker

# Move Docker root to fast storage
sudo systemctl stop docker
sudo mv /var/lib/docker /mnt/fast-storage/docker
sudo ln -s /mnt/fast-storage/docker /var/lib/docker
sudo systemctl start docker

Layer Deduplication

overlay2 deduplicates layers using content-addressable storage. If two images share the same layer, it's stored once:

# Two images sharing base layers
docker images
REPOSITORY   TAG      SIZE
node         20-alpine  180MB
node         18-alpine  175MB

# Shared layers are stored once on disk
# Total disk usage < sum of individual sizes

Storage Troubleshooting

Storage Troubleshooting

Check Disk Usage

# Overall Docker disk usage
docker system df
# TYPE           TOTAL   ACTIVE  SIZE    RECLAIMABLE
# Images         15      8       4.2GB   1.8GB (42%)
# Containers     10      5       156MB   78MB (50%)
# Local Volumes  8       5       2.1GB   500MB (23%)
# Build Cache    20      0       800MB   800MB (100%)

# Detailed view
docker system df -v

# Check specific image sizes
docker images --format "{{.Repository}}:{{.Tag}}\t{{.Size}}" | sort -k2 -h

# Check volume sizes
docker system df -v --filter type=volume

Clean Up Disk Space

# Remove stopped containers
docker container prune

# Remove dangling images
docker image prune

# Remove all unused images
docker image prune -a

# Remove unused volumes
docker volume prune

# Remove build cache
docker builder prune

# Nuclear option: remove everything
docker system prune -a --volumes --force

Common Storage Issues

Disk space exhaustion:

# Find largest images
docker images --format "{{.Repository}}:{{.Tag}} {{.Size}}" | \
  sort -k2 -h -r | head -10

# Find large volumes
docker system df -v | grep -A 100 "VOLUME NAME"

# Check build cache
docker system df -v | grep -A 100 "BUILD CACHE"

Layer bloat:

# Find image with many layers
docker history myapp:latest --format "{{.CreatedBy}}" | wc -l

# Find largest layers
docker history myapp:latest

Permission errors on volume data:

# Check volume mountpoint permissions
sudo ls -la /var/lib/docker/volumes/mydata/_data/

# Fix ownership
sudo chown -R 1000:1000 /var/lib/docker/volumes/mydata/_data/

Storage Driver Migration

To change storage drivers (rare, requires data migration):

# 1. Stop Docker
sudo systemctl stop docker

# 2. Backup images and containers
docker save -o images.tar $(docker images -q)

# 3. Edit /etc/docker/daemon.json
{
  "storage-driver": "overlay2"
}

# 4. Remove old Docker data (DESTRUCTIVE)
sudo rm -rf /var/lib/docker

# 5. Start Docker
sudo systemctl start docker

# 6. Restore images
docker load -i images.tar