Skip to content

How to Fix Docker Out of Disk Space

Reclaim disk space from Docker: find what's eating the disk, prune images and build cache safely, cap container logs, and understand the overlay2 directory.

SDSysadmin Desk October 31, 2026 8 min read
Diagram-style cover showing a full disk being reclaimed by Docker prune, with images, build cache, and container logs being cleared

A server that’s been running containers for a few months has a way of quietly filling its disk. Then a deploy fails with no space left on device, a database refuses to write, and you’re staring at a 90%-full /var/lib/docker wondering what’s safe to delete.

The good news is that most of what Docker accumulates is genuinely disposable: old image versions, stopped containers, dead build cache, and unbounded log files. The catch is that one of the cleanup commands also deletes volumes, which is where your real data lives. Get the order right and you reclaim tens of gigabytes with zero data loss.

This guide walks through finding what’s eating the disk, pruning the safe stuff first, capping logs so it doesn’t happen again, and understanding what the giant overlay2 directory actually is.

First, see what’s actually using space

Don’t prune blindly. Start with a summary so you know whether the problem is images, volumes, build cache, or logs:

docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          42        6         18.3GB    14.1GB (77%)
Containers      11        4         210MB     180MB (85%)
Local Volumes   9         5         6.2GB     2.1GB (34%)
Build Cache     310       0         9.8GB     9.8GB (100%)

The RECLAIMABLE column is what you can free without touching anything in use. In the example above, images and build cache alone hold ~24 GB of reclaimable space. Add -v for the per-item detail when you need to find the single biggest offender:

docker system df -v

That lists every image, container, and volume with its size, so you can spot the 6 GB image you forgot about or the volume that’s grown out of control.

Prune the safe things first

Work from lowest risk to highest. The first two commands almost never cause problems.

Remove dangling images — layers with no tag, left behind by rebuilds:

docker image prune

Remove the build cache, which is often the biggest single consumer on a build server:

docker builder prune

Remove stopped containers:

docker container prune

Each prompts for confirmation and reports how much it freed. If you want to clear all unused images, not just dangling ones, add -a — but be aware that pulls everything back next time you need it:

# Removes every image not used by a container — more aggressive
docker image prune -a

Prune commands by risk

docker image prune Low risk. Removes dangling (untagged) images only.
docker builder prune Low risk. Clears build cache. Slower next build, no data loss.
docker container prune Low risk. Removes stopped containers. Running ones are untouched.
docker image prune -a Medium. Removes all unused images; they re-pull when needed.
docker volume prune High. Deletes unused volumes — this is real data.
docker system prune --volumes Highest. Everything above plus volumes, in one shot.

The one command that deletes data

docker system prune is the convenient catch-all. By itself it removes stopped containers, unused networks, dangling images, and build cache — and it leaves volumes alone:

docker system prune

The dangerous variant adds --volumes:

# This DELETES unused volumes — and their data
docker system prune --volumes

The word “unused” is the trap. A volume is “unused” if no running or stopped container is currently attached to it. A named volume from a database container you removed last week counts as unused — and pruning it deletes the database. People run --volumes to free space, not realizing their data volumes qualify.

Cap your container logs

If docker system df shows modest image/volume usage but the disk is still full, the culprit is often logs. The default json-file logging driver stores everything a container writes to stdout/stderr, with no size limit. A container that logs a line per request can produce gigabytes over weeks.

Find the offenders. On Linux, log files live next to each container’s data:

sudo du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail

The fix is to enable log rotation. Set it globally in the daemon config so every new container inherits a cap:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Then restart Docker to apply it:

sudo systemctl restart docker

That keeps at most three 10 MB files per container — 30 MB max instead of unbounded growth. You can also set it per container at run time:

docker run -d --log-opt max-size=10m --log-opt max-file=3 nginx

Or in Compose:

services:
  app:
    image: myapp:latest
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

What overlay2 actually is

If you’ve poked around /var/lib/docker, you’ve seen overlay2 and probably panicked at its size. It’s not junk — it’s where Docker stores the layered filesystems.

Every image is a stack of read-only layers. Every running container adds a thin writable layer on top. The overlay2 storage driver assembles these into the filesystem each container sees. So overlay2 growing reflects three things:

  • Images you’ve pulled or built (each layer stored once, shared across images).
  • Container writable layers — anything a container writes that isn’t in a volume.
  • Stopped containers still holding their writable layer.

That second point is a frequent surprise. If an app writes large files to a normal path inside the container instead of to a mounted volume, that data lands in the container’s writable layer inside overlay2, and it grows without showing up as a “volume.” The fix is to mount a volume for data that grows — see bind mounts vs named volumes for where data should actually live.

Docker Desktop is a bit different

On Docker Desktop (Mac/Windows), containers run inside a Linux VM, and all of /var/lib/docker lives in a single virtual disk image on your host. Pruning inside Docker frees space in the VM, but the host-side disk image file doesn’t always shrink automatically.

If the VM disk has grown and won’t release space to your host after pruning, use the Docker Desktop UI — Settings → Resources → Disk — or its purge/reclaim option to compact the disk image. On Windows with WSL2, you may need to compact the WSL virtual disk to return the freed space to Windows.

Set up a maintenance routine

Keep Docker disk usage in check

  • Run docker system df monthly to spot growth early
  • Enable log rotation in daemon.json (max-size + max-file)
  • Schedule docker image prune and docker builder prune on build hosts
  • Store all persistent data in named volumes, not container layers
  • Never run --volumes prune without checking docker volume ls first
  • Back up data volumes before any aggressive cleanup

A simple safe cron job for a build server clears images and cache without ever touching volumes:

#!/usr/bin/env bash
docker container prune -f
docker image prune -af
docker builder prune -af

Note the absence of any --volumes flag — that’s deliberate. This reclaims the disposable space on a schedule while leaving your data alone.

Wrapping up

When Docker fills the disk, resist the urge to delete files by hand. Run docker system df to see where the space went, prune images and build cache first because they’re safe and usually the biggest win, and treat anything with --volumes as a data-destroying command that needs a backup and a second look. Then cap your logs in daemon.json so the disk doesn’t silently refill.

Most “out of disk” incidents trace back to two habits: uncapped logs and data written into container layers instead of volumes. Fix those two and the problem rarely comes back. For the deeper cleanup workflow, see cleaning Docker images, containers, and volumes, and browse more in the Docker & Containers guides.

Frequently asked questions

How do I see what Docker is using disk space for?

Run docker system df for a summary of images, containers, local volumes, and build cache, with a reclaimable column. Add -v for a per-item breakdown so you can see exactly which images, volumes, and build cache entries are the biggest. Start here before pruning anything.

What is the safest way to free Docker disk space?

Start with docker image prune to remove dangling images, then docker builder prune for build cache. Both are low-risk. Only run docker system prune --volumes or docker volume prune once you've confirmed no anonymous volume holds data you need, because volume pruning deletes data permanently.

Why is my overlay2 directory so large?

/var/lib/docker/overlay2 holds the layered filesystems for images and the writable layers of containers. It grows from unused images, stopped containers, and data written inside containers instead of into volumes. Don't delete files in it by hand — use docker prune commands, which clean it safely.

Why do my Docker logs fill up the disk?

By default the json-file logging driver keeps container stdout/stderr with no size limit, so a chatty container can write gigabytes. Set max-size and max-file in /etc/docker/daemon.json (or per container) to cap and rotate logs, then restart Docker.

Does docker system prune delete my volumes?

Not by default. docker system prune removes stopped containers, unused networks, dangling images, and build cache, but leaves volumes alone. It only removes volumes if you add the --volumes flag. Named volumes that aren't attached to a container are the usual hidden data risk.

Can I delete files in /var/lib/docker manually?

No. Deleting files under /var/lib/docker by hand corrupts Docker's internal state and can break the daemon. Always reclaim space through docker prune commands. If the daemon is already broken, stopping Docker and removing the whole directory resets everything — but that destroys all images, containers, and volumes.

Sources & further reading

Official vendor documentation referenced while writing this guide.

SD

Sysadmin Desk

Infrastructure & Cloud

Hands-on guidance for infrastructure, virtualization, and containers — Hyper-V, VMware, Docker, and the day-to-day operations work that keeps environments running.

MCSA Guru provides independent, educational IT guidance. Microsoft, Windows, Windows Server, Microsoft 365, Exchange, and Microsoft Teams are trademarks of Microsoft Corporation; Docker is a trademark of Docker, Inc. MCSA Guru is not affiliated with or endorsed by Microsoft or Docker. Always test changes in a safe environment before applying them in production.

Related guides

Fixing something right now?

Jump straight into the guide library or search for the exact error or task you are dealing with.