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:
- Check the writable layer — if found, return it
- Check image layers top-to-bottom — return the first match
- If not found, return file not found
When a container writes a file (copy-on-write):
- The file is copied from the read-only layer to the writable layer
- The modification is applied to the writable copy
- 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