Typical disk space consumed by Docker Desktop on a developer's Mac
Docker Desktop on macOS stores everything inside a single disk image file called Docker.raw (or Docker.qcow2 on older versions). This file grows as you pull images, run containers, and build projects -- but it never automatically shrinks, even after you delete containers and images.
This guide covers every way to reclaim Docker disk space on your Mac, from quick one-liners to nuclear options.
Unlike Linux where Docker stores files directly in /var/lib/docker, Docker Desktop for Mac uses a Linux VM. All Docker data lives inside a single disk image:
# Docker Desktop 4.x (default location)
~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
# Older versions may use:
~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.qcow2
# Check the actual size
ls -lh ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
du -h (not ls -lh) to see actual disk usage.
Other Docker-related locations on macOS:
| Location | What It Contains | Typical Size |
|---|---|---|
~/Library/Containers/com.docker.docker/ |
VM disk image (Docker.raw), logs, configs | 10--200+ GB |
~/Library/Group Containers/group.com.docker/ |
Docker Desktop settings, extensions | 50--500 MB |
~/.docker/ |
CLI config, auth tokens, plugins | 1--50 MB |
/Applications/Docker.app |
Application binary | ~1.5 GB |
Before cleaning, check what's taking space:
# Summary of Docker disk usage
docker system df
# Detailed breakdown
docker system df -v
Example output:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 47 3 18.27GB 15.81GB (86%)
Containers 5 2 1.43GB 1.12GB (78%)
Local Volumes 12 2 8.54GB 7.21GB (84%)
Build Cache 89 0 12.4GB 12.4GB (100%)
To check the actual Docker.raw file size on disk:
# Apparent size (what Docker allocated)
ls -lh ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
# Actual disk usage (real space consumed)
du -h ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
The fastest way to reclaim space with one command:
# Remove stopped containers, unused networks, dangling images, build cache
docker system prune
# Also remove ALL unused images (not just dangling ones)
docker system prune -a
# Also remove unused volumes (careful!)
docker system prune -a --volumes
# Skip the confirmation prompt
docker system prune -a -f
docker system prune -a --volumes removes ALL unused images and volumes. You'll need to re-pull images and recreate volumes. This is safe if you don't have important data in Docker volumes.
What each flag removes:
| Command | Removes | Typical Space Saved |
|---|---|---|
docker system prune |
Stopped containers, unused networks, dangling images, build cache | 2--20 GB |
docker system prune -a |
+ all unused images | 5--50 GB |
docker system prune -a --volumes |
+ unused volumes | 10--100+ GB |
Images are usually the biggest space consumer. Most developers accumulate dozens of unused images over time.
# List all images sorted by size
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | sort -k3 -h
# List dangling images (untagged, no container using them)
docker images -f "dangling=true"
# Remove all dangling images
docker image prune
# Remove ALL unused images (not used by any container)
docker image prune -a
# Remove a specific image
docker rmi image_name:tag
# Remove all images matching a pattern
docker images | grep "myapp" | awk '{print $3}' | xargs docker rmi
| Image | Size | Leaner Alternative |
|---|---|---|
ubuntu:latest |
~77 MB | alpine:latest (~7 MB) |
node:latest |
~1.1 GB | node:alpine (~180 MB) |
python:latest |
~1 GB | python:slim (~150 MB) |
postgres:latest |
~430 MB | postgres:alpine (~240 MB) |
openjdk:latest |
~470 MB | eclipse-temurin:alpine (~340 MB) |
-alpine or -slim base images in your Dockerfiles. The difference adds up fast -- a project with 10 images could save 8+ GB just by switching bases.
Docker's build cache (BuildKit) is often the largest hidden consumer of disk space. It stores intermediate layers from every docker build you've ever run.
# Check build cache size
docker buildx du
# Detailed build cache breakdown
docker buildx du --verbose
# Clear ALL build cache
docker builder prune -a
# Clear build cache older than 24 hours
docker builder prune --filter "until=24h"
# Clear build cache older than 7 days
docker builder prune --filter "until=168h"
RUN, COPY, and ADD instruction in your Dockerfile creates a cached layer. If you build 10 different projects with different base images and dependencies, the cache can easily reach 20--50GB.
Docker volumes persist data beyond container lifecycle. Old volumes from deleted projects pile up quietly.
# List all volumes with size
docker system df -v | grep -A 100 "Local Volumes space usage"
# List volumes
docker volume ls
# Find dangling (unused) volumes
docker volume ls -f "dangling=true"
# Remove all unused volumes
docker volume prune
# Remove a specific volume
docker volume rm volume_name
# Remove all volumes (DESTRUCTIVE -- removes database data etc.)
docker volume rm $(docker volume ls -q)
docker volume inspect volume_name
This is the most frustrating part of Docker on macOS. Even after running docker system prune -a --volumes, the Docker.raw file might still be 50GB+. That's because the virtual disk doesn't automatically shrink after data is deleted.
This creates a fresh, small Docker.raw file. You'll need to re-pull all images.
On Docker Desktop 4.x with VirtioFS, you can try triggering a TRIM/FSTRIM operation:
# Enter the Docker VM
docker run --rm -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i bash
# Inside the VM, run fstrim
fstrim -v /var/lib/docker
# Exit
exit
When nothing else works, or when Docker.raw has grown to 100GB+, a complete removal is the most effective approach:
# 1. Quit Docker Desktop completely
osascript -e 'quit app "Docker"'
# 2. Remove Docker.raw (the big one)
rm -rf ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
# 3. Optionally remove ALL Docker data
rm -rf ~/Library/Containers/com.docker.docker
rm -rf ~/Library/Group\ Containers/group.com.docker
rm -rf ~/.docker
# 4. Restart Docker Desktop -- it will create a fresh, small Docker.raw
open -a Docker
Time to go from 100GB Docker.raw to a fresh ~1GB one
After restart, Docker creates a new Docker.raw at minimal size. Re-pull only the images you actually need:
# Only pull what you need for current projects
docker compose pull # in your project directory
Docker Desktop -> Settings -> Resources -> Advanced -> Virtual disk limit. Set this to a reasonable value (32GB is fine for most developers).
# Bad: Single stage, keeps all build tools in final image
FROM node:20
WORKDIR /app
COPY . .
RUN npm ci && npm run build
CMD ["node", "dist/main.js"]
# Good: Multi-stage, final image only has runtime
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/main.js"]
# .dockerignore
node_modules
.git
.env
*.md
dist
coverage
.next
__pycache__
Switch from node:20 (1.1GB) to node:20-alpine (180MB). Same for Python, Ruby, and Java images.
Add this to your shell profile (~/.zshrc):
# Weekly Docker cleanup reminder
docker_cleanup() {
echo "Docker disk usage:"
docker system df
echo ""
echo "Run 'docker system prune -a' to clean up"
}
# Auto-cleanup containers older than 48 hours
alias docker-clean='docker system prune -a --filter "until=48h" -f'
# Add to crontab (crontab -e)
# Every Sunday at 3 AM: prune Docker, keep images used in last 7 days
0 3 * * 0 docker system prune -a --filter "until=168h" -f >> /tmp/docker-prune.log 2>&1
Docker Desktop 4.30+ includes built-in resource management:
If you use Docker in CI/CD locally (e.g., testing GitHub Actions with act), CI runners download massive images. Clean up after CI test runs:
# After running local CI tests
docker system prune -a -f --filter "label=com.github.actions.runner"
Docker is just one of many space consumers on a developer Mac. If you also use Xcode, Node.js, Homebrew, pip, CocoaPods, or Cargo, you likely have 50--100GB of caches spread across 15+ locations.
Free, open-source macOS menu bar app that detects Docker cache, Xcode DerivedData, node_modules, Homebrew, pip, CocoaPods, and 10+ more locations. Shows sizes in real-time -- clean what you want, keep what you need.
brew tap bysiber/cleardisk && brew install --cask cleardisk
ClearDisk shows Docker cache alongside all your other developer caches in a single menu bar dropdown, so you can see the full picture without running multiple terminal commands.
| Task | Command |
|---|---|
| Check disk usage | docker system df |
| Quick cleanup | docker system prune |
| Deep cleanup | docker system prune -a --volumes |
| Clean build cache | docker builder prune -a |
| Remove dangling images | docker image prune |
| Remove unused volumes | docker volume prune |
| Check Docker.raw size | du -h ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw |
| Full reset | Docker Desktop -> Troubleshoot -> Clean / Purge data |
| GUI cleanup (all caches) | brew tap bysiber/cleardisk && brew install --cask cleardisk |
The Docker.raw file is a sparse disk image that grows but doesn't shrink automatically. After pruning, the space is freed inside the VM but the file stays the same size on your Mac. Use Docker Desktop's "Clean / Purge data" or manually delete and restart to reclaim the host disk space.
No. docker system prune only removes stopped containers, unused networks, dangling images, and build cache. Running containers and their images are never touched.
Yes, but quit Docker Desktop first. When you restart Docker, it creates a fresh Docker.raw. You'll lose all images, containers, and volumes -- equivalent to a factory reset.
Weekly docker system prune is a good habit. Monthly docker system prune -a for deeper cleanup. Or use a cron job to automate it.