Using Docker prune Correctly: Cleaning Up Containers, Images, and Volumes

With docker prune, you can remove unused containers, images, and volumes to free up disk space. Includes examples and best practices for real projects.

Bernd Fischer

Bernd Fischer

01. Nov 2024 · 4 min read

Using Docker prune Correctly: Cleaning Up Containers, Images, and Volumes

Overview of prune

The various docker prune commands allow you to selectively remove unused Docker resources. These include stopped containers, unreferenced images, unused networks, and—depending on the command—also volumes.

Especially on development machines or build systems, such resources accumulate over time. However, before you simply remove everything, you should first check where Docker is actually using disk space:

docker system df

This provides an overview of images, containers, volumes, and the build cache.

prune is then a tool for cleanup—not for diagnosis.


Removing Stopped Containers

Stopped containers remain after their execution and can continue to occupy disk space.

You can remove all stopped containers with the following command:

docker container prune

Docker displays a warning before deletion and asks for confirmation.

If you want to intentionally skip this prompt:

docker container prune --force

Running containers are not removed this way.

Beforehand, you can see which stopped containers exist:

docker ps -a

That way, you know exactly what the cleanup will affect.


Removing Unused Volumes

Volumes store data independent of a container's lifecycle. This makes them useful—but also potentially dangerous when cleaning up carelessly.

You can remove volumes that are no longer used with the following command:

docker volume prune

Without confirmation:

docker volume prune --force

Before deleting volumes, you should check which are available:

docker volume ls

You can inspect a single volume more closely:

docker volume inspect <volume-name>

Important: A volume may contain data you still need later, even if no container is currently using it.


Removing Unreferenced Images

Docker stores images and image layers locally. Especially after frequent builds, many old or unreferenced images can accumulate.

With:

docker image prune

You remove by default so-called dangling images.

Without confirmation:

docker image prune --force

If you also want to remove all currently unused images:

docker image prune --all

This is considerably more aggressive.

It is worthwhile to look at existing images beforehand:

docker image ls

This way, you can better judge whether you are just removing build leftovers or also images you might need again later.


Removing Unused Networks

Docker Compose and manually started containers often create custom networks.

Unused networks can be removed with:

docker network prune

Or without confirmation:

docker network prune --force

Which networks currently exist is shown by:

docker network ls

Only networks not currently used by containers are removed.


Removing Multiple Unused Resources at Once

With:

docker system prune

Docker cleans up multiple resource types simultaneously.

These include, among others:

  • stopped containers
  • unused networks
  • dangling images
  • parts of the build cache

Volumes are kept by default.

With:

docker system prune --all

Additionally, all unused images are removed.

Even more aggressive is:

docker system prune --all --volumes

This also includes unused volumes.

Caution:
docker system prune --all --volumes should not be used reflexively as a default solution. Check beforehand which images and volumes are still needed and whether important data is stored there.


Practical Example

Assuming docker system df shows:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          18        3         12.4GB    8.7GB
Containers      9         2         1.1GB     860MB
Local Volumes   7         4         5.6GB     1.2GB
Build Cache     42        0         9.3GB     9.3GB

Then it makes more sense not to delete everything immediately but to proceed selectively.

First, stopped containers could be removed:

docker container prune

Then images no longer needed:

docker image prune

If the build cache is the largest disk consumer:

docker builder prune

I would only touch volumes once it is clear what data they hold.

This distinction is crucial:

Diagnose
    ↓
betroffene Ressource finden
    ↓
gezielt aufräumen
    ↓
erneut prüfen

instead of:

Speicher knapp
    ↓
alles löschen

Systematic Investigation of Docker Issues

prune helps with cleaning up. However, it does not explain why Docker takes up so much disk space or why certain resources keep being created.

The same applies to many other Docker problems: containers exit immediately, ports are unreachable, data seems lost, or builds suddenly become slow.

If you want not only to resolve such issues but also to diagnose them systematically, you can find 20 practical diagnostic and repair recipes for developers in my book Docker Troubleshooting.

Topics covered include:

  • Disk usage by images, containers, volumes, and build cache
  • Logs, exit codes, and health checks
  • Network issues with Docker Compose
  • Ports, listeners, and readiness
  • Volumes, bind mounts, and file permissions
  • .env, container environment, and build secrets
  • Slow builds, cache invalidation, and image layers

More about the book


Docker Is Only Part of the Solution

Cleanup commands help remove accumulated resources. In real projects, however, problems often arise from the overall system structure: unclear deployments, poorly separated services, or inconsistent build and runtime processes.

Especially with Django projects, it is therefore worthwhile to look beyond Docker itself and consider the application's architecture.

If you are interested in how a maintainable Django project can be structured, you will find a detailed explanation here:

How to structure a maintainable Django project