Docker Disk Usage: Clean Up Images, Containers, and Build Cache Without Breaking Your Setup

Docker Disk Usage: Clean Up Images, Containers, and Build Cache Without Breaking Your Setup

Your dev machine got slower. The fan spins up. df -h shows your root partition at 91%. And Docker is the first suspect — because it usually is.

Docker doesn’t delete anything on its own. Every docker build you’ve ever run left layers behind. Every container you stopped is still on disk. Every docker compose experiment parked a full image. None of it gets cleaned unless you ask. This guide walks through exactly what’s eating your disk and the safe commands to reclaim it — plus how to make cleanup automatic so you never have to think about it again.

First: See what’s actually eating the disk

Before deleting anything, measure. Docker ships a built-in report:

docker system df

This shows, in one table: images, containers, local volumes, and build cache — each with the count, how much is active versus reclaimable, and the total. The RECLAIMABLE column is the number you care about. That’s the disk you can get back without touching anything you’re currently using.

For the full breakdown — which specific images are taking up space — use the verbose flag:

docker system df -v

The three biggest offenders

  1. Dangling images and build cache. Every docker build with changed layers leaves the old layers as dangling — no tag, no container using them, just sitting there. BuildKit’s cache accumulates even faster, which is why a month of builds can quietly eat 10–20 GB.
  2. Stopped containers and unused networks. Stopping a container doesn’t remove it. docker compose down without --volumes leaves them behind too.
  3. Anonymous volumes. Volumes created by docker run -v without a named volume are orphaned the moment the container is removed — but their data stays on disk.

The safe cleanup command

Docker’s own one-shot sweep handles all of the above in a single command:

docker system prune -a

This removes stopped containers, unused networks, all images not referenced by a running container (that’s the -a), and the entire build cache. It does not remove volumes — which is both the safety feature and the trap, covered below.

You’ll get a prompt listing exactly what will be deleted and how much space you’ll free. Confirm it, and you’re done. Most dev machines reclaim 5–20 GB on the first run.

For a quicker pass that skips the build cache, drop the flag:

docker system prune

What NOT to prune

The commands above are safe because they only touch unreferenced data. The one that isn’t safe is the volume sweep:

docker volume prune   # ⚠️ deletes database data

Volumes are where databases live. A Postgres or MySQL container’s data directory is a volume. If you prune volumes on a machine where you’ve run docker compose for a project with a database, you delete that database — permanently. There’s no trash can for volumes. Only run docker volume prune when you’re certain every volume on the machine is disposable, and even then, back up anything you care about first.

Same rule for the aggressive image sweep:

docker image prune -a --filter "until=720h"

The --filter here is your friend: it only removes images older than 30 days, leaving recent builds intact. Filters turn a blunt tool into a surgical one.

Make cleanup automatic

Manual cleanup is the kind of thing you do once and then forget for three months — which is exactly why the disk fills up again. The fix is to make it a habit you don’t have to think about:

  • Alias the safe sweep. Add alias dprune='docker system prune -a' to your shell. One word, no prompt-diving.
  • Run it weekly. A cron job (0 9 1 docker system prune -f) keeps the build cache from ever getting out of hand. The -f flag skips the confirmation prompt — fine for the weekly sweep since it never touches volumes.
  • Check the numbers monthly. docker system df takes two seconds. If RECLAIMABLE is back above 10 GB, your cleanup cadence needs to be tighter.

This is exactly the kind of thing a dev-environment starter pack should handle for you: cleanup helpers wired in from day one, so a fresh setup never accumulates cruft in the first place.

Why this matters for your whole workflow

A clean Docker environment isn’t just about disk space. Pruned build caches mean your next docker build starts from a known state instead of a stale layer that’s been wrong for three weeks. Freed disk space means your editor stops thrashing. And a predictable cleanup routine means the “docker is eating my disk” panic never happens at the worst possible moment — like right before a deadline.

Docker is a genuinely great tool. It just needs a janitor.

Automate it with DevKit

If you’re tired of hand-rolling cleanup scripts for every machine you touch, that’s the problem DevKit was built to solve. It’s a one-command developer environment starter pack that includes:

  • Docker helpersdocker-cleanup and docker-prune commands that run the safe sweep for you, with the volume protection built in
  • Terminal dotfiles.bashrc, .zshrc, aliases, and prompt customization so every new machine feels like home
  • Git aliasesgit-cleanup and git-sync shortcuts for the daily git chores that slow you down
  • Project init scripts — instant scaffolding for common stacks so new projects start fast

It’s the perfect companion to ScaffoldKit for generating production-ready project skeletons — or get both in the ScaffoldKit + DevKit Bundle for $45. One command to set up your environment, one command to keep it clean.

More from the Ezra Labs shop

Keeping your machine clean is half the battle — DevKit ships the docker-cleanup helpers as part of a full environment starter pack, and Reviews Pro keeps the customer side of your shop healthy. Explore everything at the Ezra Labs shop.

Similar Posts