Docker Says It's Empty. Docker.raw Is 60 GB. Here's Why.
Docker Desktop on macOS stores everything in one growing VM disk image that never shrinks on its own. Why `docker system prune` appears to do nothing, and how to actually get the space back.
You ran docker system prune -a. It reported reclaiming 40 GB. Your Mac has exactly as much free
space as before.
This is the single most confusing storage problem on a developer’s Mac, and it is not a bug.
Why it happens
Docker containers are a Linux technology. macOS is not Linux, so Docker Desktop runs a Linux virtual machine, and everything — images, layers, containers, volumes, build cache — lives inside that VM’s filesystem.
That filesystem is one large file on your Mac, usually named Docker.raw.
When you delete an image, Docker frees space inside the VM’s filesystem. The blocks become
available for the VM to reuse. But the file on your Mac that contains that filesystem does not
shrink, for the same reason deleting files inside a .dmg does not make the .dmg smaller.
So Docker.raw only ever grows. Pull a 3 GB image, delete it, pull another 3 GB image, and the file
is 6 GB even though Docker honestly reports 3 GB in use.
Confirm it on your machine
What Docker thinks:
docker system df
What is actually on disk — find the file rather than guessing the path, because it has moved between Docker Desktop versions:
find ~/Library/Containers/com.docker.docker -name "*.raw" -exec du -sh {} \; 2>/dev/null
On most installs that lands in
~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw, but do not hardcode it — check.
A gap between the two numbers is the space you are looking for.
duversus Finder. On APFS the image file is sparse, sodureports blocks actually allocated while Finder shows the logical size.duis the number that matters — it is the space you cannot use for anything else.
Step 1: clean inside the VM first
Nothing else works until the space is free inside the filesystem.
# What is safe to remove, itemised
docker system df -v
# Dangling images and stopped containers only — conservative
docker system prune
# Everything not currently used by a running container
docker system prune -a
# Same, plus unused named volumes
docker system prune -a --volumes
Read this before running the last one. --volumes removes unused named volumes, which is
where local development databases live. If you have a Postgres container whose data you care about
and it is not running right now, that data is inside a named volume, and this deletes it. Check
first:
docker volume ls
The build cache is usually the biggest single item and is always safe to drop — it only makes the next build slower:
docker builder prune -a
Step 2: actually shrink the file
Now the space is free inside the VM but the file is still huge. Options, best first:
Let Docker Desktop reclaim it
Recent Docker Desktop versions can return unused blocks to macOS automatically, and the settings pane exposes a manual trigger. Open Docker Desktop → Settings → Resources → Advanced and look for a disk usage section with a reclaim or clean-up control. This is the safe path and it preserves everything you have not pruned.
Restart Docker Desktop
Some versions compact the image during a clean shutdown and restart. Quit Docker Desktop fully — from the menu bar, not just closing the window — wait, and start it again. Then re-measure. It is free to try.
The nuclear option
Settings → Troubleshoot → Reset to factory defaults (older versions: “Clean / Purge data”)
deletes Docker.raw outright and recreates it empty. You get every gigabyte back immediately.
You also lose everything: all images, all containers, all volumes, all build cache. Everything re-pulls from registries and rebuilds from Dockerfiles, so for most development setups the real cost is bandwidth and one slow afternoon. But if a container holds the only copy of some data, back it up first:
docker run --rm -v my_volume:/data -v "$PWD":/backup alpine \
tar czf /backup/my_volume.tar.gz -C /data .
Stop it recurring
Cap the disk image. In Settings → Resources, the virtual disk limit is a hard ceiling. Set it to something you can live with — 64 GB is plenty for most work — and Docker cannot silently consume 200 GB. This is the highest-value five seconds in this article.
Prune on a schedule. A weekly docker system prune -a is a reasonable habit, or a fortnightly
docker builder prune -a if you build large images often.
Use multi-stage builds. Every intermediate layer of a naive Dockerfile is stored. Multi-stage builds discard the build environment and keep only the final artefact, which shrinks both what you push and what you store.
Consider an alternative runtime. OrbStack and
Colima both run Docker workloads on macOS with more
conservative disk behaviour. OrbStack in particular reclaims space back to the host as you go, which
sidesteps this entire article. Colima keeps its own disk image under ~/.colima — check that too if
you use it:
du -sh ~/.colima 2>/dev/null
The general lesson
Every macOS tool that runs a Linux VM has this shape: a file that grows and does not shrink, with an in-VM view that disagrees with your Mac’s view. Docker is simply the one most developers hit.
DevCruft shows the image file at its true on-disk size alongside everything else on your Mac, so the gap between “Docker says 4 GB” and “this file is 61 GB” is visible instead of something you have to go looking for.
More sources of the same problem: the full developer storage guide.