How to clear dead Docker overlay2 storage directory safely without breaking daemon

Root Cause Diagnosis

Accumulation of dead directories in /var/lib/docker/overlay2 occurs when the Docker daemon crashes, loses daemon state tracking, or experiences ungraceful container terminations before completing layer cleanup. Manually executing rm -rf /var/lib/docker/overlay2/* breaks the Docker daemon by destroying the active image layer database and local SQLite/bolt key-value stores located in /var/lib/docker/image/overlay2/imagedb/. This creates orphaned references between Docker’s internal layer graph metadata and the actual backing filesystem, causing future container instantiations to fail with missing driver layer errors.

Quick Fix

Run the native Docker system prune with the volume flag to safely unmount and remove all unreferenced overlay2 layer diffs:

docker system prune -a --volumes -f

If disk space is still unreleased, reboot or restart the Docker service to release orphaned, deleted file handles still held open by the kernel:

sudo systemctl restart docker

Step-by-Step Resolution

Step 1: Identify Dead and Orphaned Overlay2 Directories

Map active, registered Docker container/image layer IDs against existing directories on disk to identify true orphans.

  1. Find all active layer diff hashes registered by Docker:sudo docker inspect $(sudo docker ps -a -q) | grep -i "WorkDir\|MergedDir" | awk '{print $2}' | tr -d '",' | awk -F'/' '{print $(NF-1)}' | sort -u > /tmp/active_layers.txt
  2. List all layer directories present on disk:sudo ls -1 /var/lib/docker/overlay2 | grep -v "l" | sort -u > /tmp/disk_layers.txt
  3. Compare both lists to isolate orphaned directories present on disk but missing from Docker metadata:comm -23 /tmp/disk_layers.txt /tmp/active_layers.txt > /tmp/dead_layers.txt cat /tmp/dead_layers.txt

Step 2: Unmount Stale Overlay Mount Points

Orphaned layer deletions fail or cause system-wide kernel panics if mount points are still active in the VFS layer.

  1. Check if any identified dead directory is actively mounted:grep overlay /proc/mounts | grep -f /tmp/dead_layers.txt
  2. Force unmount any active stale mount points:for mnt in $(grep overlay /proc/mounts | grep -f /tmp/dead_layers.txt | awk '{print $2}'); do sudo umount -f "$mnt" done

Step 3: Stop the Docker Daemon Safely

To avoid race conditions and corruption of /var/lib/docker/link, stop the container runtime entirely before modifying storage directories directly.

sudo systemctl stop docker
sudo systemctl stop docker.socket

Step 4: Safely Remove Orphaned Directories

Remove only the specific orphaned layer directories verified in Step 1. Do not modify the /var/lib/docker/overlay2/l symlink directory directly.

  1. Delete isolated orphan directories using xargs:cat /tmp/dead_layers.txt | while read layer; do if [ -n "$layer" ] && [ -d "/var/lib/docker/overlay2/$layer" ]; then sudo rm -rf "/var/lib/docker/overlay2/$layer" fi done
  2. Rebuild missing dynamic directory symlinks in the shortened symlink lookup table (/var/lib/docker/overlay2/l) by removing broken dangling symlinks:sudo find /var/lib/docker/overlay2/l -xtype l -delete

Step 5: Restart the Daemon and Verify Database Integrity

Start the daemon service and confirm database integrity across existing images and containers:

sudo systemctl start docker
sudo docker info
sudo docker ps -a

Why This Fails for Some Users

  • Active Systemd/Containerd Storage Driver Mismatch: On systems running Kubernetes or containerd independently alongside Docker, containerd manages its own overlay2 directories under /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/. Deleting directories under /var/lib/docker/overlay2 does not free disk space used by Kubernetes pods running on containerd.
  • XFS/Ext4 d_type Support Missing: Older Linux kernels or legacy filesystems formatted without ftype=1 prevent overlay2 from tracking file types properly. When clearing directories on systems with ftype=0, Docker fails to rebuild layer structures upon daemon start. Verify d_type support with xfs_info /var/lib/docker | grep ftype.
  • Stuck Open File Handles (EBUSY Errors): If a process inside a crashed container hangs or holds locks on files within an overlay diff directory, rm -rf returns Device or resource busy. You must identify and terminate the blocking process using sudo lsof +D /var/lib/docker/overlay2/<layer_id> before the directory can be unlinked.
  • RHEL/CentOS SELinux Context Corruption: On RHEL/CentOS systems with SELinux in Enforcing mode, manual file operations in /var/lib/docker/overlay2 strip required security contexts (container_var_lib_t). After manual cleanup, you must restore contexts before starting containers:sudo restorecon -R -v /var/lib/docker/overlay2
See also  Resolving Linux error: No space left on device when disk space shows 50% free (Inodes full)

Leave a Comment