Fix Docker 'no space left on device' Error

Quick answer
Docker's 'no space left on device' error almost always means the build cache, stopped containers, or dangling images have filled the disk — not your actual application data. Here's how to reclaim the space in under 2 minutes.
- Step 1: See what Docker is using
- Fix: Run the right prune command
- Cause: What actually fills the disk
- On CI/CD runners
- Prevent it from coming back
5 min read · DevOps & Platform
Fix Docker 'no space left on device' Error
error: failed to solve: failed to copy: write /var/lib/docker/tmp/...: no space left on device
or when starting a container:
docker: Error response from daemon: ... no space left on device.
This almost never means your application's data volume is full. It means /var/lib/docker — where Docker stores images, containers, volumes, and build cache — has consumed all available disk space.
Step 1: See what Docker is using
docker system dfTYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 47 12 28.4GB 22.1GB (77%)
Containers 3 1 142MB 40MB (28%)
Local Volumes 8 4 4.2GB 1.1GB (26%)
Build Cache 0 0 18.6GB 18.6GB
This shows you exactly what's using space and how much is reclaimable. Build cache is usually the biggest culprit on developer machines and CI systems.
# Also check actual disk usage
df -h /var/lib/dockerFix: Run the right prune command
Option 1 — Safe cleanup (non-destructive to running workloads)
docker system pruneRemoves: stopped containers, dangling images (untagged), unused networks, build cache.
Does NOT remove: named volumes, images referenced by a container (running or stopped).
Add -f to skip the confirmation prompt:
docker system prune -fOption 2 — Aggressive cleanup (removes all unused images too)
docker system prune -aSame as above but also removes all unused images — not just dangling ones. Any image not currently referenced by a running or stopped container is deleted.
On a CI runner that builds images but doesn't run long-lived containers,
-ais safe to run after every build. The image will just be re-pulled or rebuilt next time.
Option 3 — Remove only the build cache
docker builder prune # Remove dangling build cache
docker builder prune -a # Remove all build cache
docker builder prune -a -f # Non-interactiveBuild cache is the fastest growing culprit. On a developer machine or CI runner, this alone often reclaims 10–30GB.
Option 4 — Remove specific things
1# Stopped containers only
2docker container prune
3
4# Dangling images only (untagged, not referenced by any container)
5docker image prune
6
7# All unused images
8docker image prune -a
9
10# Unused volumes (careful — this deletes data)
11docker volume pruneCause: What actually fills the disk
Build cache (most common)
Every docker build creates layers in the build cache. Without pruning, this grows indefinitely. Multi-stage builds with large base images (node, python, java) fill it quickly.
docker system df -v # Verbose — shows individual cache entriesDangling images
Failed builds, intermediate stages, and old image versions leave untagged images behind.
docker images -f dangling=true # List dangling images
docker image prune # Remove themStopped containers
If you don't use --rm when running containers, stopped containers accumulate.
docker ps -a --filter status=exited # List stopped containers
docker container prune # Remove themLogs
Container logs are stored at /var/lib/docker/containers/<id>/<id>-json.log. Without a log rotation policy, a verbose container can fill the disk.
# Find large log files
find /var/lib/docker/containers -name "*-json.log" -exec du -sh {} \; | sort -rh | head -10Set a default log size limit in /etc/docker/daemon.json:
1{
2 "log-driver": "json-file",
3 "log-opts": {
4 "max-size": "50m",
5 "max-file": "3"
6 }
7}Then restart Docker: systemctl restart docker
Stuck on this in production?
We debug exactly this kind of issue for platform teams — usually in a single working session.
On CI/CD runners
Build cache accumulates fast on CI runners. Add a prune step at the end of each build job:
# GitHub Actions example — prune at end of each job
- name: Prune Docker build cache
run: docker builder prune -a -fAlternatively, mount the build cache to a separate volume with a size limit so it can't consume the root disk.
Prevent it from coming back
- Use
--rmfor temporary containers:docker run --rm ...deletes the container on exit. - Set log rotation in
daemon.json(see above). - Schedule regular prune: add
docker system prune -fto a cron job or CI cleanup step. - Use a separate partition for
/var/lib/dockeron long-running machines so Docker can't fill the OS disk.
Quick reference
docker system df # See what's using space
docker system prune -f # Safe cleanup (no volumes)
docker system prune -af # Aggressive (removes all unused images too)
docker builder prune -af # Build cache only
docker volume prune -f # Volumes only (removes data — be careful)See also
- Docker Multi-Stage Builds & Image Optimisation — smaller images = less disk pressure
- Fix: Kubernetes ImagePullBackOff — image-related errors in Kubernetes
For the other Docker daemon error people hit on a fresh install, see permission denied on the Docker socket.
Frequently Asked Questions
Which prune command should I run?
Start with docker system df to see where the space actually went, then prune that category. Build cache is frequently the largest and least expected entry on a machine that builds often. Avoid a blanket prune with volumes included unless you are certain — that deletes data.
Is it safe to prune volumes?
Only if you know nothing needs them. Volume pruning removes unused anonymous volumes by default — exactly where a database's data sits when someone forgot to declare it in Compose — and unused named volumes too if you add --all. This is the one prune that destroys data rather than reclaiming cache.
Why does the disk fill up again so quickly on CI runners?
Because every build writes new layers and cache, and nothing removes them between jobs. Prune on a schedule or at job start, and cap the build cache size rather than relying on manual cleanup. A runner that fills its disk mid-build fails in confusing ways.
The daemon says space is free but builds still fail. Why?
Check inodes as well as bytes — a filesystem can exhaust inodes while showing free space, and many small layer files is exactly the workload that does it. Also confirm you are looking at the filesystem holding Docker's data root, which may not be the one you expect.
Official References
- Dockerfile best practices — layer caching, image size and build ordering
- Dockerfile reference — every instruction and its semantics
Was this article helpful?
Be the first to rate this article
Related Topics
Found this useful? Share it.


