Docker / Storage

Docker Desktop says 2GB. Docker.raw says 90GB. Both are true.

Published Aug 29, 2026 · 7 min read · macoptimize

You run docker system prune -a, Docker reports reclaimed space, and Finder still shows the same free space as before. Nothing is broken. Docker Desktop on macOS runs a Linux virtual machine, and everything inside it lives in a single file on your Mac:

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

That file is sparse. It starts small, grows as you pull images and write data, and almost never gives space back. Delete a 5GB container inside the VM and the Linux file system marks those blocks free, but macOS keeps the allocation. The number Docker Desktop shows you and the number Finder shows you measure two different things.

Check the real size first

du -h ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
ls -lh ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw

du reports the blocks actually allocated on disk, which is the number that matters for free space. ls reports the logical size, which is the maximum the disk image is allowed to grow to. A file that shows 64G in ls and 41G in du is holding 41GB of real disk, and pruning inside Docker will not necessarily release any of it.

Option 1: prune first, and measure after

docker system df
docker system prune -a --volumes

The first command breaks usage into images, containers, volumes and build cache, which tells you which one is actually large. The second removes every unused image, all stopped containers, unused networks and anonymous volumes. Read that flag list carefully: it deletes images you may have built locally, so re-pulling from a registry needs to be acceptable.

After pruning, run du again. Freed space inside the VM rarely appears on the Mac immediately.

Option 2: rebuild the disk image

This is the reliable way to return space to macOS, and it deletes everything inside Docker:

  • Open Docker Desktop and go to Settings.
  • Open Resources and find Disk image size.
  • Move the slider down, for example from 64GB to 40GB.
  • Click Apply and restart.

Docker deletes the old image and creates a fresh one, so the space comes back immediately. Stop and think before doing it: containers, images, volumes and any local database data inside them are gone. It is the right move for a laptop where everything is reproducible from a compose file, and the wrong move if the only copy of a development database lives in a volume.

Back up volumes you care about first. Named volumes hold real data. Run docker volume ls, then dump anything important with docker run --rm -v name:/data -v "$PWD":/backup busybox tar czf /backup/name.tgz -C /data . before you resize.

Option 3: find it visually and stop guessing

The reason this surprises people is that Docker.raw is buried inside a hidden container path that no storage panel surfaces. A treemap makes it obvious. In our own scan of a developer Mac the Docker image appeared as a single block larger than every project folder combined, which turned a vague feeling of "something is using my disk" into a specific, measurable decision.

What macoptimize does with it

The Clean tab lists the Docker disk image with its real allocated size, alongside the Docker build cache, and leaves it unchecked by default because clearing it is destructive. The Optimize tab has a one click prune for the safe parts, so you can reclaim the build cache without touching your volumes.

Keeping it under control

  • Run docker system prune (without -a) weekly. It clears dangling images and build cache only.
  • Set the disk image limit lower than you think you need. Docker will not grow past it, which forces you to notice.
  • Re-check du on the raw file monthly. Growth of a few gigabytes a month is normal on an active project.

Everything Docker stores on a Mac

Four locations account for nearly all of it, and they behave differently:

PathHoldsTypical size
Containers/com.docker.docker/Data/vms/0/data/Docker.rawImages, containers, volumes, build cache20GB to 120GB
Group Containers/group.com.dockerSettings, CLI plugins, logs100MB to 2GB
~/.dockerCredentials, contexts, configUnder 50MB
Library/Caches/com.docker.dockerInstaller and update downloads200MB to 3GB

Only the first one is worth attacking for space, and only two things change its size in practice: pruning a lot, or rebuilding it.

Ranked by how much space you actually get back

  • Rebuild the disk image. Returns everything Docker was holding, instantly, and costs you every image and volume. Highest yield, highest cost.
  • Trim the file system inside the VM. Returns recently freed blocks without deleting anything, using the command below. Moderate yield, no data loss.
  • docker system prune -a --volumes. Frees a lot inside the VM, and the space reaches macOS only on the next trim or restart.
  • docker image prune. Removes dangling images only. Low yield, very safe, good for a weekly habit.
  • docker builder prune. Clears the build cache, which on a busy machine is often several gigabytes. Safe, and Docker rebuilds it as you work.

Trimming without deleting anything

The disk image is a Linux file system inside a virtual machine. When Docker deletes files, that file system marks the blocks free, and macOS still counts them as allocated, because nothing has told the virtual disk that the blocks are available. You can pass that message through:

docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i fstrim -av

Run it after a prune and check du on Docker.raw again. On a healthy setup it returns several gigabytes that pruning alone left behind. Treat it as a convenience rather than a guarantee: it depends on how the virtual machine is configured, and if the number does not move, rebuilding the disk image is the answer that always works.

Why some data survives every prune

Prune is careful by design. It removes stopped containers, unused networks, dangling images and the build cache by default, and it leaves three things alone:

  • Named volumes, because a database volume with no container attached still looks like data worth keeping.
  • Images that a stopped container references, unless you pass -a.
  • Anything currently running, which is why a container that restarts itself is never cleaned.

The practical result is that a machine with three dormant projects can hold 30GB of images and volumes that no prune will touch until you name them. docker system df -v lists them individually with sizes, which is the fastest way to spot the one you no longer need.

What macoptimize does here

The Clean tab measures the Docker disk image and reports its real allocated size next to every other cache on the machine. You see that Docker.raw is 41GB while Xcode holds 22GB, decide which one is the actual problem, and clear it from the dashboard instead of guessing in Terminal.

Stopping the growth in the first place

Three habits keep the file from reaching triple digits:

  • Run docker builder prune weekly. The build cache is the fastest growing part and the least painful to lose.
  • Set the disk image to something honest, like 40GB, rather than leaving it at the maximum. Docker grows into the limit, and a limit you can see is a limit you notice.
  • Delete images you built for a test and never used again. docker images sorted by size takes ten seconds and usually finds one worth removing.

FAQ

Does docker system prune -a actually free space on my Mac?

It frees space inside the virtual machine, and macOS usually does not see it immediately. The disk image stays the same size on disk until the file system inside it is trimmed or the image is rebuilt. Measure with du on Docker.raw before and after to see what really happened.

Is it safe to delete Docker.raw manually?

It works, and it is brutal. You must quit Docker Desktop completely first, and afterwards every image, container and volume is gone with no way to recover them. Rebuilding the disk image from the Settings screen achieves the same result with less risk of leaving the app in a broken state.

Why is Docker.raw bigger than the sum of my images?

Because sparse files do not shrink. The virtual disk grows in blocks as data is written and keeps the allocation after files are deleted inside it, and volumes that survive a prune are still in there. Over time the gap between what Docker reports and what the file occupies can reach tens of gigabytes.

Will prune delete my database volumes?

Not the named ones. docker system prune leaves named volumes alone even with -a. Adding --volumes removes anonymous volumes, which are the ones Docker creates for containers that declare a volume without naming it. Check docker volume ls before you decide.

Can I move Docker.raw to an external drive?

Yes, Docker Desktop lets you choose the disk image location in its settings, and an external SSD is a legitimate place for it. Expect slower container performance on a USB connection, and remember that unplugging the drive while Docker runs is not a graceful shutdown.

Or let it do the work

macoptimize scans the folders in this guide, shows the real sizes, and clears what you select. $20 one time, covers 2 Macs.