Docker’s disk usage can balloon rapidly, and reclaiming that space often feels like a black art.

Here’s how to get a handle on it, with a focus on seeing the actual data and understanding the commands.

Let’s start by seeing what’s taking up space. This is the command you’ll use constantly:

docker system df

This command breaks down Docker’s disk usage by images, containers, local volumes, and build cache. It’s your primary dashboard. Pay close attention to the "RECLAIMABLE" column.

Understanding the Components

  1. Images: These are the read-only templates that containers are built from. When you pull a new version of an image or build one, Docker stores it. Old, unused images are prime candidates for cleanup.

  2. Containers: These are running instances of images. Even stopped containers can consume disk space, especially if they’ve generated logs or written data to their writable layer.

  3. Volumes: These are the preferred mechanism for persisting data generated by and used by Docker containers. They live outside the container’s writable layer and are managed by Docker. Unused volumes can accumulate significant data.

  4. Build Cache: When you build Docker images, Docker caches intermediate layers to speed up subsequent builds. This cache can grow quite large.

The Cleanup Commands

The most powerful command for general cleanup is docker system prune. Use it with caution, as it removes a lot of data.

docker system prune -a --volumes
  • -a: This flag tells Docker to remove all unused images, not just dangling ones. Dangling images are those not tagged and not referenced by any container.
  • --volumes: This flag is crucial. By default, docker system prune does not remove unused local volumes. Adding this flag cleans up volumes that are not currently attached to any container.

Why it works: This command iterates through all Docker objects (images, containers, networks, build cache) and removes any that are not currently in use by a running container. For volumes, "unused" means "not attached to any container."

Targeted Cleanup

While prune is effective, you often want more granular control.

Cleaning Up Unused Images:

docker image prune -a
  • -a: Removes all images that are not associated with at least one container. This includes dangling and untagged images.

Why it works: This command specifically targets image layers. It identifies images that have no containers (running or stopped) referencing them and removes their layers from the host’s filesystem.

Cleaning Up Unused Containers:

docker container prune

This command removes all stopped containers.

Why it works: Stopped containers still occupy disk space in their writable layers. This command removes those layers for containers that are no longer running.

Cleaning Up Unused Volumes:

docker volume prune

This command removes all local volumes that are not currently used by at least one container.

Why it works: Volumes that are no longer attached to any container represent orphaned data. This command safely removes those volumes and their data.

Cleaning Up Build Cache:

docker builder prune

This command cleans up the build cache, which is used to speed up docker build operations.

Why it works: Docker caches intermediate image layers during builds. This command removes cached layers that are no longer referenced by any build history.

Manual Inspection and Removal

Sometimes, you need to dive deeper.

Listing All Images:

docker images -a

This shows all images, including intermediate layers. The SIZE column is what you’re looking for.

Removing a Specific Image:

docker rmi <IMAGE_ID>

You can get the <IMAGE_ID> from docker images.

Why it works: This command removes the specified image and its associated layers. If other images depend on those layers, Docker might prevent removal unless you force it (-f), which is generally not recommended unless you know what you’re doing.

Listing All Volumes:

docker volume ls

This shows all local volumes. The VOLUME NAME is what you need.

Removing a Specific Volume:

docker volume rm <VOLUME_NAME>

Why it works: This command detaches the volume from any container it might be associated with (if any) and then removes the volume’s data directory from the host’s filesystem.

The "Gotcha" and the Next Step

The most common mistake is forgetting the --volumes flag when running docker system prune. This leaves a significant amount of disk space occupied by unused volumes. You might run docker system prune and still see your disk usage barely change, only to discover later that it was your volumes.

The next challenge you’ll likely encounter is dealing with the logs generated by your containers. Docker containers can fill up disks rapidly with log files if not properly managed.

Want structured learning?

Take the full Docker course →