Docker

Docker: no space left on device

Docker filled the disk. Find what actually consumed it — images, build cache, volumes or the container logs that prune never touches — and stop it recurring.

The error

ERROR: failed to solve: failed to register layer:
write /usr/lib/.../libLLVM.so: no space left on device

docker: Error response from daemon: mkdir /var/lib/docker/overlay2/...:
no space left on device.

Docker has filled its storage location — usually /var/lib/docker — with image layers, stopped containers, build cache, volumes and logs that nothing cleaned up.

The useful question is not "how do I free space" but which of those five is actually responsible, because the fix differs and one of them is invisible to docker system prune.

Find out what is consuming it

Always start here rather than pruning blindly:

docker system df
TYPE            TOTAL   ACTIVE   SIZE      RECLAIMABLE
Images          47      6        18.2GB    14.1GB (77%)
Containers      31      4        890MB     712MB (80%)
Local Volumes   12      5        24.6GB    18.2GB (73%)
Build Cache     284     0        9.4GB     9.4GB (100%)

-v breaks it down per object, which tells you exactly which volume or image is the problem:

docker system df -v

And check whether Docker is even the culprit:

df -h /var/lib/docker
sudo du -sh /var/lib/docker/* | sort -rh | head
18G   /var/lib/docker/overlay2
24G   /var/lib/docker/volumes
31G   /var/lib/docker/containers      ← logs live here

That third line is the one people miss.

The quick fix

docker system prune -a --volumes

This removes all stopped containers, all unused images, all unused networks, all build cache and all volumes not attached to a container.

Be careful with --volumes. It deletes data. A database volume whose container is stopped counts as unused and will go, permanently. Run docker volume ls first and confirm you recognise everything on the list.

The safer incremental version:

docker container prune       # stopped containers
docker image prune           # dangling images only
docker builder prune         # build cache — usually the biggest safe win
docker image prune -a        # every image no container uses
docker volume prune          # LAST, and only after checking

Build cache is almost always the safest large reclaim. It regenerates automatically and the only cost is a slower next build.

The cause prune does not fix: container logs

If pruning freed far less than docker system df suggested, this is why.

docker system prune never touches container logs. A long-running container using the default json-file driver with no rotation writes unbounded output:

sudo du -sh /var/lib/docker/containers/* | sort -rh | head -5
28G   /var/lib/docker/containers/a1b2c3d4e5f6...

A single chatty container reaching tens of gigabytes is entirely normal after a few months.

Truncate one immediately:

sudo truncate -s 0 /var/lib/docker/containers/<id>/<id>-json.log

Then stop it recurring, which is the part that matters. Set a global default in /etc/docker/daemon.json:

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

This applies to newly created containers only — existing ones keep their original configuration until recreated.

Volumes that outlive everything

Volumes are excluded from the default prune deliberately, because they hold data. They also accumulate invisibly:

docker volume ls -f dangling=true
docker system df -v | head -30

The usual culprit is anonymous volumes. An image declaring VOLUME /data — most database images do — creates a fresh unnamed volume on every docker run where you did not mount one. Start a Postgres container twenty times while testing and you have twenty volumes holding real data.

docker volume prune       # removes volumes no container references

Prevent it by always mounting a named volume explicitly, and using --rm on throwaway runs, which removes anonymous volumes on exit.

When the disk is too full for Docker to start

An awkward state: the daemon cannot start, so docker commands do not work either.

# Free something outside Docker first
sudo journalctl --vacuum-size=200M
sudo apt-get clean

# Then start the daemon and prune normally
sudo systemctl start docker
docker system prune -a

If Docker still will not start, deleting build cache directly is a last resort — but never delete overlay2 subdirectories by hand. That corrupts the image store, and the recovery is stopping the daemon and removing /var/lib/docker entirely, which destroys every image, container and volume on the host.

Docker Desktop is different

On macOS and Windows, Docker stores everything inside a virtual disk image. Deleting containers does not shrink that file — it grows to a high-water mark and stays there.

~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw   (macOS)

Prune inside Docker as normal, then reclaim the host space in Docker Desktop → Settings → Resources → Disk image size, or use the troubleshoot panel's clean-up. Simply raising the allocated size buys time without addressing the cause.

Stop it happening again

MeasureEffect
max-size and max-file in daemon.jsonCaps log growth — the biggest silent consumer
docker builder prune -f --filter until=168h on a timerBuild cache never accumulates
--rm on one-off runsNo stopped containers or anonymous volumes
Named volumes, mounted explicitlyNo orphaned anonymous volumes
Monitor /var/lib/docker usageAn alert before the outage

A weekly cron job covers most of it:

0 3 * * 0 docker system prune -af --filter "until=168h" >> /var/log/docker-prune.log 2>&1

The until filter keeps anything used in the last week, which makes this safe to automate in a way that a bare prune -a is not.

A checklist

  1. docker system df — which category is actually large?
  2. sudo du -sh /var/lib/docker/* — is it containers (logs) rather than images?
  3. docker builder prune first, the safest large reclaim.
  4. docker image prune -a and docker container prune.
  5. Logs → truncate now, then set max-size in daemon.json to stop it recurring.
  6. docker volume prune last, after checking docker volume ls.
  7. Docker Desktop → also reclaim the virtual disk in Settings.
  8. Schedule a weekly prune with an until filter.

Frequently Asked Questions

How do I fix "no space left on device" in Docker?

Start with docker system df to see which category is consuming space rather than pruning blindly. Then reclaim in increasing order of risk: docker builder prune for build cache, which is the safest large win, then docker image prune -a and docker container prune, and only finally docker volume prune after checking docker volume ls, since that one deletes data. If pruning frees far less than expected, the space is almost certainly in container logs, which prune never touches.

Why did docker system prune not free up space?

Because it does not touch container logs. With the default json-file driver and no rotation configured, a long-running container writes unbounded output to /var/lib/docker/containers/<id>/<id>-json.log, and tens of gigabytes from a single chatty container is common. Check with sudo du -sh /var/lib/docker/containers/* | sort -rh. Truncate the offender, then set max-size and max-file in /etc/docker/daemon.json so it cannot recur. Volumes are the other exclusion, requiring --volumes explicitly.

Is docker system prune -a --volumes safe to run?

Not without checking. It removes every stopped container, every unused image, all build cache and every volume not currently attached to a container — and that last part deletes data permanently. A database volume whose container happens to be stopped counts as unused. Run docker volume ls first and confirm you recognise everything. Without --volumes the command is much safer, since the worst outcome is re-pulling images and a slower next build.

What is taking up space in /var/lib/docker?

Run sudo du -sh /var/lib/docker/* | sort -rh to see. overlay2 holds image and container layers and is usually the largest, addressed by pruning images. volumes holds persistent data, which prune skips by default. containers holds the logs, which prune never removes and which are the most common cause of space that pruning fails to reclaim. Never delete anything under overlay2 by hand — it corrupts the image store.

How do I stop Docker filling the disk again?

Cap the logs first, by setting "log-opts": {"max-size": "10m", "max-file": "3"} in /etc/docker/daemon.json and restarting Docker — note this applies only to newly created containers. Add --rm to one-off runs so nothing accumulates. Always mount named volumes explicitly rather than letting images create anonymous ones. Then schedule a weekly docker system prune -af --filter "until=168h", which keeps anything used in the last week and is safe to automate.

Why does deleting Docker images not free space on macOS?

Because Docker Desktop stores everything inside a single virtual disk image, and that file grows to a high-water mark without shrinking when you delete things inside it. Pruning frees space within the VM but the host file stays the same size. Reclaim it through Docker Desktop's Settings under Resources, where you can shrink or reset the disk image, or via the clean-up option in the troubleshoot panel. Increasing the allocated size instead only postpones the problem.

Learn the underlying concept

Other Docker errors