If you've been working with Docker for any length of time, you've probably noticed something: things pile up fast. Old containers hanging around, dangling images eating disk space, orphaned volumes collecting dust — it's like a digital junk drawer that never stops growing.
Don't worry. In this guide, we're going to walk through everything you need to know about cleaning up your Docker environment. Whether you want to surgically remove a single container or nuke everything and start fresh, I've got you covered.
Understanding Docker Objects
Before we start deleting things, let's make sure we're on the same page about what we're actually dealing with:
- Images — Read-only templates used to create containers. Think of them as blueprints.
- Containers — Running (or stopped) instances of images. These are the actual workhorses.
- Volumes — Persistent data storage that lives outside the container's filesystem.
- Networks — Virtual networks that allow containers to communicate with each other.
Each of these objects can accumulate over time and consume significant disk space. Let's learn how to clean them up.
Checking Your Current Docker Disk Usage
First things first — let's see how much space Docker is actually using. This command gives you a nice summary:
docker system dfYou'll get output that looks something like this:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 15 3 4.723GB 3.644GB (77%)
Containers 5 1 256.3MB 245.1MB (95%)
Local Volumes 12 2 1.853GB 1.621GB (87%)
Build Cache 0 0 0B 0BSee that "Reclaimable" column? That's how much space you can potentially get back. If those numbers look scary, keep reading.
Removing Docker Containers
Containers are usually the first thing you'll want to clean up. Let's start here.
List All Containers
To see all containers, including stopped ones:
# Show running containers
docker ps
# Show ALL containers (running + stopped)
docker ps -aRemove a Specific Container
Got a specific container you want to get rid of? Grab its container ID or name and run:
docker rm container_id_or_nameIf the container is still running, Docker will complain. You can force-remove it:
docker rm -f container_id_or_nameYou can also remove multiple containers at once by listing them:
docker rm container1 container2 container3Remove All Stopped Containers
This is one of the most common cleanup tasks. Here's the quick way:
docker container pruneDocker will ask for confirmation and then remove every stopped container. If you want to skip the confirmation prompt, add the -f flag:
docker container prune -fAlternatively, you can use this slightly more old-school approach that pipes container IDs into the rm command:
docker rm $(docker ps -a -q)The -q flag returns only the container IDs, which makes piping super clean.
Stop and Remove All Containers
Need to stop everything first, then clean up? Here's the combo:
# Stop all running containers
docker stop $(docker ps -q)
# Remove all containers
docker rm $(docker ps -a -q)Removing Docker Images
Images tend to be the biggest disk space offenders. Let's deal with them.
List All Images
# List all top-level images
docker images
# List ALL images, including intermediate layers
docker images -aRemove a Specific Image
docker rmi image_id_or_nameIf the image is being used by a container (even a stopped one), you'll need to remove that container first, or force it:
docker rmi -f image_id_or_nameRemove Dangling Images
Dangling images are layers that have no relationship to any tagged image. They're essentially orphans, and they're usually safe to remove:
docker image pruneThis only removes dangling images. If you want to remove all unused images — not just dangling ones — add the -a flag:
docker image prune -aBe careful with this one! It will remove every image that isn't currently being used by a running container. If you have images you've pulled but aren't actively running, they'll be gone.
Remove Images by Pattern
Sometimes you want to remove images matching a certain pattern. Here's a handy trick using grep and awk:
# Remove all images containing "my-app" in the name
docker images | grep "my-app" | awk '{print $3}' | xargs docker rmiThis pipes matching image IDs into docker rmi. It's incredibly useful when you have dozens of tagged versions of the same app.
Removing Docker Volumes
Volumes are sneaky. They persist even after the container that created them is removed, and they can quietly eat up a lot of disk space over time.
List All Volumes
docker volume lsRemove a Specific Volume
docker volume rm volume_nameRemove All Unused Volumes
docker volume pruneThis removes all volumes that aren't currently mounted to a running container. Add -f to skip confirmation:
docker volume prune -fRemove a Container and Its Volume Together
If you want to remove a container and its associated anonymous volumes in one shot:
docker rm -v container_id_or_nameThe -v flag tells Docker to also remove anonymous volumes associated with that container. Named volumes will not be affected unless explicitly removed.
Removing Docker Networks
While we're cleaning house, let's not forget about networks. They don't take up much space, but unused ones can clutter your environment.
# List all networks
docker network ls
# Remove a specific network
docker network rm network_name
# Remove all unused networks
docker network pruneThe Nuclear Option: Remove Everything
Sometimes you just want a completely fresh start. Docker has a single command that will clean up images, containers, volumes, and networks all at once:
docker system pruneThis removes:
- All stopped containers
- All networks not used by at least one container
- All dangling images
- All build cache
Want to go even further? Add the -a and --volumes flags:
docker system prune -a --volumesThis removes everything — all unused images (not just dangling), all stopped containers, all unused networks, all unused volumes, and the build cache. It's the Docker equivalent of formatting a drive.
⚠️ Warning: This is irreversible. Any data stored in volumes that aren't backed up will be gone forever. Make absolutely sure you know what you're doing before running this in production.
Filtering With the --filter Flag
Docker's prune commands support filters, which gives you more granular control over what gets removed. For example, you can remove containers that were created more than 24 hours ago:
docker container prune --filter "until=24h"Or remove images that were created before a specific timestamp:
docker image prune -a --filter "until=2024-01-01T00:00:00"You can also filter by label:
# Remove containers with a specific label
docker container prune --filter "label=environment=staging"
# Remove containers WITHOUT a specific label
docker container prune --filter "label!=environment=production"This is incredibly handy in CI/CD environments where you want automated cleanup without accidentally removing production-related resources.
Creating a Cleanup Script
If you find yourself cleaning up Docker regularly (and you should!), consider creating a simple cleanup script:
#!/bin/bash
# docker-cleanup.sh — A simple Docker cleanup script
echo "=== Docker Cleanup Script ==="
echo ""
# Show current disk usage
echo "Current Docker disk usage:"
docker system df
echo ""
# Remove stopped containers
echo "Removing stopped containers..."
docker container prune -f
# Remove unused images
echo "Removing dangling images..."
docker image prune -f
# Remove unused volumes
echo "Removing unused volumes..."
docker volume prune -f
# Remove unused networks
echo "Removing unused networks..."
docker network prune -f
# Show updated disk usage
echo ""
echo "Updated Docker disk usage:"
docker system df
echo ""
echo "=== Cleanup complete! ==="Save it, make it executable with chmod +x docker-cleanup.sh, and run it whenever things start getting messy. You could even add it to a cron job for automated weekly cleanups.
Quick Reference Cheat Sheet
Here's a summary of every command we covered, all in one place:
# --- Containers ---
docker ps -a # List all containers
docker rm <id> # Remove specific container
docker rm -f <id> # Force remove running container
docker container prune # Remove all stopped containers
docker rm $(docker ps -a -q) # Remove all containers
# --- Images ---
docker images -a # List all images
docker rmi <id> # Remove specific image
docker image prune # Remove dangling images
docker image prune -a # Remove all unused images
# --- Volumes ---
docker volume ls # List all volumes
docker volume rm <name> # Remove specific volume
docker volume prune # Remove all unused volumes
# --- Networks ---
docker network ls # List all networks
docker network rm <name> # Remove specific network
docker network prune # Remove unused networks
# --- Everything ---
docker system prune # Remove unused data
docker system prune -a --volumes # Remove EVERYTHING unusedFinal Thoughts
Keeping your Docker environment clean isn't just about reclaiming disk space — although that's definitely a major benefit. A tidy Docker setup is easier to debug, faster to work with, and less likely to cause those weird "it works on my machine" problems that make developers pull their hair out.
My recommendation? Get into the habit of running docker system prune at least once a week during development. In CI/CD pipelines, add cleanup steps at the end of your builds. And on production servers, use filtered prune commands to safely remove old resources without risking anything critical.
Your hard drive — and your future self — will thank you.