How to Delete Docker Images: Commands, Options, and What to Consider First

Docker images can pile up fast. Every docker pull, every build, every failed experiment leaves something behind. Over time, unused images eat into disk space — sometimes gigabytes worth — and a cluttered local registry makes it harder to find what you actually need. Deleting Docker images is straightforward once you understand the commands, but the right approach depends on your environment, workflow, and what's currently running.

What Docker Images Actually Are

Before deleting anything, it helps to understand what you're working with. A Docker image is a read-only template used to create containers. Images are built in layers — each instruction in a Dockerfile adds a layer, and those layers are cached and reused across images.

This layered system is efficient, but it also means images aren't always as independent as they look. Deleting one image doesn't necessarily remove all its layers if other images share them. Docker handles this automatically — it won't delete a layer that's still referenced elsewhere.

Images also have two identifiers you'll encounter constantly:

  • Image ID — a unique hash (e.g., sha256:3f4a2b...)
  • Repository and tag — a human-readable name (e.g., ubuntu:22.04)

An image can have multiple tags pointing to the same ID, which matters when you're trying to remove something cleanly.

The Core Command: docker rmi

The primary command for removing images is:

docker rmi <image_name_or_id> 

You can reference an image by name, tag, or ID:

docker rmi ubuntu:22.04 docker rmi 3f4a2b8c1d9e 

To remove multiple images at once, list them space-separated:

docker rmi image1 image2 image3 

Important: Docker will refuse to delete an image if a container — even a stopped one — is still using it. You'll see an error like image is being used by stopped container. You either need to remove that container first (docker rm <container_id>) or use the force flag.

Force Removal

docker rmi -f <image_id> 

The -f flag forces deletion even if containers reference the image. Use this carefully — forcing removal of an image tied to a running container can cause unexpected behavior. In development environments it's generally fine; in production, it warrants more caution.

Listing Images Before You Delete 🗂️

Always know what you're working with:

docker images 

This shows repository name, tag, image ID, creation date, and size. For a more complete view including intermediate layers:

docker images -a 

To find dangling images — untagged images no longer referenced by any tagged image, typically leftover build artifacts:

docker images -f dangling=true 

Bulk Removal: Cleaning Up Efficiently

Remove All Dangling Images

docker image prune 

This removes all dangling (untagged, unreferenced) images. It's the safest bulk operation because it only targets images with no active references.

Remove All Unused Images

docker image prune -a 

Adding -a removes all images not currently used by at least one container — including tagged ones. This is more aggressive. If you pull an image for reference but haven't built a container from it yet, it goes.

Remove Everything with docker system prune

docker system prune 

This goes broader — stopped containers, unused networks, dangling images, and build cache all get cleared. Add -a to include all unused images:

docker system prune -a 

With --volumes, it also removes anonymous volumes. This is a significant cleanup operation and will prompt for confirmation by default.

Filtering by Age or Label

Docker's --filter flag gives you more control:

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

This removes unused images older than 72 hours. You can also filter by label, which is useful in environments where images are tagged with metadata during CI/CD pipelines.

Key Variables That Change Your Approach

FactorImpact on Deletion Strategy
Running containersCan't delete images in use without force
Shared base imagesLayers shared across images won't fully delete
CI/CD pipelinesAggressive pruning may break cached build layers
Docker Compose projectsCompose-managed images may need docker compose down --rmi all
Multi-stage buildsIntermediate images may appear dangling but were intentional
Registry vs. localdocker rmi only removes locally — remote registry images need separate management

Docker Compose Specifics

If you're working with Compose, the standard docker rmi command still works, but there's a more integrated option:

docker compose down --rmi all 

This stops containers, removes them, and deletes associated images in one step. Using --rmi local instead only removes images that don't have a custom tag — useful when you want to keep pulled base images but discard locally built ones.

What Doesn't Get Deleted (And Why)

A few things catch people off guard: 🤔

  • Images referenced by any container (running or stopped) are protected unless forced
  • Named volumes are not touched by image prune — only system prune --volumes handles those
  • Remote registry images are completely unaffected — docker rmi is purely local
  • Build cache survives image prune but is cleared by builder prune or system prune

This distinction between local image storage and remote registries matters a lot in team environments. Removing an image locally doesn't affect what teammates can pull, and it doesn't free up registry storage.

How Your Setup Shapes the Right Approach

A solo developer doing local experimentation has very different needs than a team running builds through a CI/CD pipeline. Prune commands that are perfectly safe on a personal laptop could disrupt build caching in a pipeline, where those cached layers represent real time savings. Similarly, a production server warrants far more caution than a development machine — forced removal or aggressive pruning without checking what's running first introduces real risk.

The frequency of your cleanup matters too. Regular, lighter pruning (dangling images only) tends to be more manageable than periodic nuclear-option cleanups that require auditing everything afterward.

How aggressive you should be with deletion depends entirely on what's running, what's shared, and what that disk space is actually worth in your specific environment.