The short version
- Docker on a Mac runs Linux in a virtual machine. Everything lives in one big disk image file,
Docker.raw. - That file grows as you build and pull, and historically did not shrink when you deleted things inside it.
docker system dfshows what is reclaimable.docker system prune -a --volumesclears it.- On current Docker Desktop the host file shrinks within seconds after pruning. Named volumes with your data are left alone.
The thing nobody tells you about Docker on a Mac
Docker runs Linux containers, and your Mac is not Linux. So Docker Desktop quietly runs a small Linux virtual machine, and everything, every image, container, volume and scrap of build cache, lives inside that VM. Crucially, the VM's entire disk is a single file on your Mac: Docker.raw, tucked away in ~/Library/Containers/com.docker.docker/Data/vms/0/data/.
Docker's own documentation says it plainly: Docker Desktop "stores Linux containers and images in a single, large disk image file in the Mac filesystem." That one design choice explains every strange thing you have noticed about Docker and disk space.
Why pruning did not seem to work
Here is the subtlety. When you run docker rmi or docker system prune, you free space inside the VM. But the Docker.raw file on your Mac does not automatically shrink to match. Docker's docs are explicit: "Space is not freed automatically when files are deleted inside running containers," and "space is only freed when images are deleted." For years this meant the file grew and grew and essentially never came back without a reset.
There is a second trap. If you check the file with ls -lh, you see its maximum logical size, not how much it actually uses, because it is a sparse file. To see real usage, use du:
# real physical size of the Docker disk image (not ls -lh) $ du -h ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
See what is actually in there
Before deleting anything, look. docker system df breaks the usage into images, containers, local volumes and build cache, and tells you how much of each is reclaimable.
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 23 4 18.4 GB 14.9 GB (80%)
Containers 9 2 1.1 GB 820 MB (72%)
Local Volumes 14 3 9.6 GB 6.2 GB (64%)
Build Cache 201 0 11.3 GB 11.3 GB (100%)
Two things usually dominate that reclaimable column. The first is dangling images: every time you rebuild a tagged image, the previous layers are orphaned and show up as <none>:<none>. The second is build cache, which BuildKit accumulates continuously and is almost always 100 percent reclaimable.
Reclaim it, step by step
The blunt instrument is docker system prune. By default it removes stopped containers, unused networks, dangling images and unused build cache: all rebuildable, all safe. Add -a to also remove tagged images you are not currently using, and --volumes to clear unused anonymous volumes.
# safe default: stopped containers, dangling images, unused build cache $ docker system prune # aggressive: also unused tagged images and anonymous volumes $ docker system prune -a --volumes # or target just the usual suspects $ docker image prune # dangling images $ docker builder prune -a # all build cache
Docker never auto-removes volumes, "because to do so could destroy data." A named volume is where your database and other persistent data live, and the default prune leaves those alone. Only --volumes removes unused anonymous volumes. Before running the aggressive form, glance at docker volume ls and make sure nothing you care about is sitting in an anonymous volume.
Getting the space back to macOS
Pruning frees space inside the VM. On modern Docker Desktop, reclaiming it on the Mac side is now fast: with the current .raw disk format the host space "should be reclaimed within a few seconds" after you prune. If it does not, there is an explicit reclaim step, and as a last resort you can shrink the maximum size in Settings or use Troubleshoot to clean or purge all data (which recreates a fresh, empty image).
# nudge host reclamation if the file hasn't shrunk $ docker run --privileged --pid=host docker/desktop-reclaim-space # confirm on the Mac side $ du -h ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
"Docker does not auto-shrink" is true for the host file, not the whole story. Pruning genuinely frees blocks inside the VM; it is only the handback to macOS that is not automatic. Since Docker Desktop 4.20 and the .raw format, that handback is quick, so do not assume reclamation is impossible, just that it needs a nudge.
The OrbStack contrast
If this whole dance annoys you, it is worth knowing it is a Docker Desktop design choice, not a law of nature. OrbStack, a drop-in alternative that runs the same Docker CLI, uses a sparse disk that "automatically shrinks when you delete data." A fresh install is under 10 MB, and it manages the disk fully dynamically. If Docker's disk behaviour has burned you repeatedly, OrbStack is the usual recommendation, though its data lives in a different place (under a Group Containers folder) and the exact path is worth confirming on your version.
A reliable routine
- Run
docker system dfto see what is reclaimable. - Glance at
docker volume lsso you do not prune data you want. - Run
docker system prune(or-a --volumesif you have reviewed). - Check
du -honDocker.raw; if it did not shrink, run the reclaim container.
Done every few weeks, this keeps Docker from quietly reclaiming tens of gigabytes of your disk. Real-world reports of Docker images sitting at 40, 60, even 100 GB are not rare; they are just what happens when build cache and dangling layers are never swept up.
Docker space, read live and labelled
StorageSage reads Docker directly, separates dangling images, build cache and orphaned volumes, and flags Compose projects whose folder is gone. Because Docker removes these itself rather than via the Trash, StorageSage tells you that up front before anything is freed.
Download for macOSSources
- Docker — macOS FAQ (single disk image, space not freed automatically, reclaim step);
docker system df,docker system prune,docker image prune,docker builder pruneand volume pruning reference. - OrbStack — FAQ and efficiency documentation (auto-shrinking sparse disk).
- Docker issue tracker and engineering write-ups documenting real-world disk-image ballooning.