Developer
Clean Up Docker on Mac Without Losing Data
Docker Desktop can use tens of gigabytes because images, writable container layers, build cache, and volumes live inside a Linux virtual disk. These categories are not equally disposable. Build cache is usually reproducible; a database volume may be the only copy of important data. Safe cleanup starts with Docker's inventory, not its broadest prune command.
Why Docker's space does not come back
Docker Desktop on macOS runs a Linux VM and normally stores its data in a sparse
virtual disk named Docker.raw. The location and disk limit are visible in Docker
Desktop's Resources settings and can change when you move the disk image. A sparse
file has a maximum logical size and a smaller physical allocation, so ls -lh alone
can make it look much larger than the capacity it currently occupies.
See what Docker itself thinks it is using:
docker system df -v
The detailed view breaks down images, containers, local volumes, and build cache.
"Reclaimable" means Docker sees no current reference that requires the object; it does
not prove that you will not need a stopped container, old image, or volume tomorrow.
Also inspect docker ps -a and docker volume ls before pruning.
Start with narrow cleanup
Always reclaim from inside Docker, not by deleting its virtual-disk file. Begin with the category you understand:
docker builder prune --filter until=168h
docker image prune
docker container prune
The first command removes build cache older than seven days; adjust the age to match
your work. The next two prompt before removing dangling images and stopped containers.
Run docker system df -v again after each step so you can see which action mattered.
docker system prune is a broader convenience command. Adding -a removes all unused
images, not only dangling layers. Adding --volumes expands the operation to unused
anonymous volumes, which can contain database files or other state. Do not make
docker system prune -a --volumes a default cleanup command. Before any volume prune,
identify the volume's owning project and export or back up data that cannot be rebuilt.
Reclaiming the disk image itself
After a prune, free blocks exist inside the Linux filesystem before macOS necessarily receives them from the sparse disk. Docker Desktop can reclaim that allocation over time. Use its documented Resources controls to inspect disk usage, limit, and location. A factory reset is not compaction: it destroys local containers, images, volumes, and settings. Use it only when that complete loss is intentional and important volume data has been exported.
Under the hood: why the file grows and will not shrink
Docker Desktop runs a Linux VM, and Docker.raw is that VM's virtual disk: a sparse
file that grows as the guest writes but does not automatically hand space back to
macOS when the guest deletes. Removing an image marks blocks free inside the VM's
filesystem, but the host file only shrinks if the guest issues TRIM/discard and
Docker Desktop can use discard and compaction to return eligible blocks. The timing
depends on its version and disk-image implementation. This is why a logical cleanup
and host-level capacity change need to be measured separately, and why deleting the
host file is equivalent to destroying the entire Docker environment.
Where a disk map helps
A disk map such as Mole's Analyze view can reveal the virtual disk and its physical footprint. Docker's own CLI must decide which internal objects are referenced. The two views answer different questions: macOS shows where capacity is allocated, while Docker explains what that allocation contains.
A safe order of operations
Run docker system df -v, identify old projects and stateful volumes, export unique
data, and prune one category at a time. Recheck both Docker's internal totals and
macOS physical capacity. Use broad prune flags only after reviewing their expanded
scope, and never use a factory reset as a routine space-recovery shortcut. The fastest
safe win is usually old build cache, not unknown volumes.