Guides

How to stop and remove Docker containers, images and volumes

Docker remove container and image commands: docker stop, rm -f, rmi, prune with -a and --volumes, the image is being used error and docker system df.

Published ~10 min read
On this page

Short answer: stop a container with docker stop NAME and delete it with docker rm NAME, or do both with docker rm -f NAME. Delete an image with docker rmi IMAGE once no container uses it. docker container prune, docker image prune -a and docker volume prune clear out what is unused, and docker system df shows the space.

any system with Docker
docker stop web            # stop the container named web
docker rm web              # delete it (it must be stopped)
docker rmi nginx:1.27      # delete the image, once no container uses it
docker system df           # how much space Docker uses, and how much is reclaimable

The commands and messages here follow Docker’s CLI reference on docs.docker.com. Docker was not run for this article, so treat the output blocks as examples of the format; container IDs and sizes on your machine will differ, and on installs that use the containerd image store some error messages may be worded differently.

Cheat sheet: stop and remove

TaskCommand
Stop a containerdocker stop web
Stop every running containerdocker stop $(docker ps -q)
Kill a container that will not stopdocker kill web
Remove a stopped containerdocker rm web
Stop and remove in one stepdocker rm -f web
Remove a container and its anonymous volumesdocker rm -v web
Remove all stopped containersdocker container prune
Remove every container, running or notdocker ps -aq | xargs -r docker rm -f
Remove an imagedocker rmi nginx:1.27
Remove dangling imagesdocker image prune
Remove every image no container usesdocker image prune -a
Remove a volumedocker volume rm pgdata
Remove unused volumes, named ones includeddocker volume prune -a
Remove everything unused at oncedocker system prune
Remove a Compose project with its images and volumesdocker compose down --rmi all -v
See what takes the spacedocker system df

docker rm is short for docker container rm, and docker rmi for docker image rm; both spellings do the same thing. Wherever a command takes a container, the name, the full ID or any unique start of the ID works: docker ps -a shows all three.

Stop a container: docker stop and docker kill

any system with Docker
docker stop web              # SIGTERM, then SIGKILL after 10 seconds
docker stop -t 60 web        # give a database a minute to shut down cleanly
docker stop $(docker ps -q)  # every running container
docker kill web              # SIGKILL straight away

docker stop sends the container’s main process SIGTERM (or the signal the image sets with STOPSIGNAL), waits 10 seconds by default, and then sends SIGKILL. A container that always takes the full 10 seconds usually runs its program under a shell that does not pass the signal on. docker kill skips the wait; use it for a container that hangs, not as the normal way to stop a database. In a Compose project, docker compose stop stops every service of the project.

The container comes back after a reboot

That is its restart policy. A container started with --restart always stays stopped after docker stop, but Docker starts it again when the daemon restarts, which includes every reboot of the server. unless-stopped remembers that you stopped it. Change the policy on the existing container, or remove the container:

any system with Docker
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' web
docker update --restart=no web
docker stop web

Remove containers: docker rm

docker rm deletes stopped containers, any number at once. On a running one it refuses:

Example output · docker rm web while web is running
Error response from daemon: cannot remove container "/web": container is running: stop the container before removing or force remove

Older Engine versions word it You cannot remove a running container ... Stop the container before attempting removal or force remove. Either stop it first or use -f, which kills it with SIGKILL and removes it in one step, without the clean shutdown docker stop would allow. What goes with the container: its writable layer (every file it changed or created outside a volume), its log, and its name, which becomes free for a new container. What stays: the image, named volumes and bind-mounted folders on the host. -v also removes the container’s anonymous volumes, more on those below.

any system with Docker · remove in bulk
docker container prune                                  # all stopped containers, asks first
docker container prune --filter "until=24h"             # only those created over 24 hours ago
docker ps -aq --filter status=exited | xargs -r docker rm   # the same by hand
docker ps -aq | xargs -r docker rm -f                   # every container, running or not

xargs -r runs nothing when the list is empty, where docker rm $(docker ps -aq) would complain that it needs at least one argument. A container started with docker run --rm removes itself when it exits, which keeps one-off containers from piling up in the first place.

Remove images: docker rmi

any system with Docker
docker images                  # list them, with name, tag, ID and size
docker rmi nginx:1.27          # by name and tag
docker rmi 605c77e624dd        # by ID
docker image rm myapp:old myapp:older   # several at once

Removing by name and tag first removes that tag. If the same image has other tags, only the tag goes (Untagged: myapp:old) and the image stays for the others; once the last tag is gone, its layers are deleted too (Deleted: sha256:...). Layers that another image shares stay on disk until no image needs them.

“Image is being used by stopped container”

Docker will not delete an image that any container was created from, including a stopped one, because the container needs the image’s layers to start again. The message depends on whether you named the image by tag or by ID:

Example output · docker rmi myapp:1.0
Error response from daemon: conflict: unable to remove repository reference "myapp:1.0" (must force) - container 0b3a2c9d1e4f is using its referenced image 2d4ba2b1a9d0
Example output · docker rmi 2d4ba2b1a9d0
Error response from daemon: conflict: unable to delete 2d4ba2b1a9d0 (must be forced) - image is being used by stopped container 0b3a2c9d1e4f

Find every container made from the image, remove them, then remove the image:

any system with Docker
docker ps -a --filter ancestor=myapp:1.0
docker rm 0b3a2c9d1e4f
docker rmi myapp:1.0

-f is not the shortcut it looks like here: docker rmi -f removes the tag, but the image stays on disk as an untagged <none> image for as long as the stopped container exists. Against a running container even -f stops with (cannot be forced) - image is being used by running container. The third common refusal, (must be forced) - image is referenced in multiple repositories, means the ID you gave has several tags; remove the tags one by one, or use -f with the ID to remove them all.

Remove all Docker images

any system with Docker
docker image prune -a                          # every image no container uses (asks first)
docker ps -aq | xargs -r docker rm -f          # or, for a clean slate: all containers first,
docker images -aq | xargs -r docker rmi -f     # then every image

The first line is what most people want: it keeps the images your containers, stopped ones included, still need. The last two delete everything, after which every service has to pull or build its image again before it can start.

Dangling vs unused images, and docker image prune

Dangling imageUnused image
What it isAn image with no tag that no container refers to, shown as <none>:<none>Any image, tagged or not, that no container (running or stopped) was created from
How it appearsRebuilding or pulling a tag moves the tag to the new image and leaves the old one untaggedYou pulled or built it, and nothing runs it right now
Removed bydocker image prunedocker image prune -a
RiskPractically noneThe image has to be pulled or rebuilt before its next use
any system with Docker
docker images -f dangling=true                 # list dangling images
docker image prune                             # remove them
docker image prune -a --filter "until=168h"    # unused images created more than 7 days ago
docker builder prune                           # build cache, a separate pile
Example prompt · docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N]

Add -f to skip the question in scripts and cron jobs. The build cache, which docker build fills on a machine that builds images, is not an image and is cleared by docker builder prune or by docker system prune.

Remove volumes, and the data-loss trap

A volume holds data outside the container’s writable layer, so it survives docker rm. There are two kinds. A named volume is one you named, such as -v pgdata:/var/lib/postgresql/data. An anonymous volume gets a 64-character random name. Docker creates one when an image declares a VOLUME and you start it without mounting anything there, and when you pass -v with only a container path, such as -v /data.

any system with Docker
docker volume ls                      # all volumes
docker volume ls -f dangling=true     # volumes no container refers to
docker volume rm pgdata               # remove one
docker volume prune                   # unused anonymous volumes
docker volume prune -a                # unused named volumes as well

Since Docker Engine 23.0, docker volume prune removes only unused anonymous volumes; -a (--all) is what includes named ones, and older guides that say otherwise predate the change. A volume still attached to a container, even a stopped one, is refused with remove pgdata: volume is in use - [0b3a2c9d1e4f...]: remove the container first.

docker system prune and docker system df

any system with Docker
docker system df              # totals per type
docker system df -v           # per image, container and volume
docker system prune           # stopped containers, unused networks, dangling images, build cache
Example output · docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          14        4         6.21GB    4.87GB (78%)
Containers      6         4         212MB     38MB (17%)
Local Volumes   9         3         2.3GB     1.1GB (47%)
Build Cache     41        0         1.6GB     1.6GB
Example prompt · docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - unused build cache

Are you sure you want to continue? [y/N]

-a widens “dangling images” to every image without a container and clears all build cache. --volumes adds unused anonymous volumes, with the warning above; named volumes are left out of docker system prune, so remove those with docker volume rm or docker volume prune -a. RECLAIMABLE in docker system df is the space held by objects that nothing uses right now.

Remove a Docker Compose project

in the folder with compose.yaml
docker compose down                      # containers and networks; volumes and images stay
docker compose down -v                   # also the project's named and anonymous volumes
docker compose down --rmi all            # also every image the services use
docker compose down --rmi local -v       # images built here (no image: name), and volumes
docker compose down --remove-orphans     # also containers of services no longer in the file

down -v deletes the named volumes declared in the file’s volumes: section, which is usually where the database lives; volumes marked external: true are left alone. More Compose commands are in the Docker commands cheat sheet.

When the disk is full

On a server, these commands usually come up because the disk ran out. Work through it in order, safest first:

  • docker system df to see whether images, containers, volumes or build cache are the problem.
  • docker image prune, docker builder prune and docker container prune: the cheap wins.
  • docker image prune -a if old image versions pile up after every deploy.
  • Large container logs: a container’s log is deleted with the container, and log rotation keeps the next one small, as set up in installing Docker on Ubuntu and Debian.

Never delete folders under /var/lib/docker by hand: Docker’s own records of images and layers then no longer match the disk, and the prune commands stop being able to clean up. When the space is not Docker’s at all, No space left on device walks through finding what else fills it. And if docker itself is missing on the machine, see docker: command not found.

Errors when stopping and removing

MessageCauseFix
container is running: stop the container before removing or force removedocker rm on a running containerdocker stop first, or docker rm -f
unable to remove repository reference ... container ... is using its referenced imageA container, stopped or running, was made from the imagedocker ps -a --filter ancestor=IMAGE, remove those, then rmi
image is being used by stopped containerThe same, with the image named by IDRemove the container first
(cannot be forced) - image is being used by running containerA running container uses itStop and remove that container
image is referenced in multiple repositoriesThe ID has several tagsRemove each tag, or docker rmi -f ID
volume is in useA container, even a stopped one, still refers to the volumeRemove the container, then the volume
No such containerTypo, or it was already removed (--rm)docker ps -a for the exact name

Frequently asked

How do I delete a container in Docker?

Stop it with docker stop NAME, then delete it with docker rm NAME, or do both with docker rm -f NAME. docker ps -a lists every container with its name and ID. Removing a container deletes its writable layer and its log; the image, named volumes and bind-mounted folders stay.

How do I remove all Docker images?

docker image prune -a removes every image that no container, running or stopped, was created from. To delete absolutely everything, remove the containers first with docker ps -aq | xargs -r docker rm -f, then the images with docker images -aq | xargs -r docker rmi -f. Every service then has to pull or build its image again.

Why does docker rmi say the image is being used by a stopped container?

Docker keeps any image a container was created from, even a stopped one, because the container needs its layers to start again. List those containers with docker ps -a --filter ancestor=IMAGE, remove them with docker rm, then run docker rmi again. docker rmi -f only removes the tag and leaves the image on disk.

Does docker system prune delete volumes?

Not by default. docker system prune removes stopped containers, unused networks, dangling images and build cache. With --volumes it also removes unused anonymous volumes, which can hold a database's data. Named volumes need docker volume rm, docker volume prune -a or, for a Compose project, docker compose down -v.

Related articles

All guides