ChatGPT解决这个技术问题 Extra ChatGPT

How to remove old Docker containers

This question is related to Should I be concerned about excess, non-running, Docker containers?.

I'm wondering how to remove old containers. The docker rm 3e552code34a lets you remove a single one, but I have lots already. docker rm --help doesn't give a selection option (like all, or by image name).

Maybe there is a directory in which these containers are stored where I can delete them easily manually?

You should also consider cleaning orphaned docker volumes. I often find that they consume much more space than old containers and old images. Good script for removing orphaned docker volumes is available at: github.com/chadoe/docker-cleanup-volumes.
You can also use docker runwith the --rm flag which would make the container ephemeral, removing all container files after the run.
With docker 1.13 (Q4 2016), you can also consider the new docker system prune command. See my answer below.
Use the docker management tool Portainer We can manageall the old containers, non using volumes and images by using this tool Its a simple management UI for dockers Please refer my update below on how to deploy the application

s
slhck

Since Docker 1.13.x you can use Docker container prune:

docker container prune

This will remove all stopped containers and should work on all platforms the same way.

There is also a Docker system prune:

docker system prune

which will clean up all unused containers, networks, images (both dangling and unreferenced), and optionally, volumes, in one command.

For older Docker versions, you can string Docker commands together with other Unix commands to get what you need. Here is an example on how to clean up old containers that are weeks old:

$ docker ps --filter "status=exited" | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm

To give credit, where it is due, this example is from https://twitter.com/jpetazzo/status/347431091415703552.


Similar command to remove all untagged images: docker images | grep "<none>" | awk '{print $3}' | xargs docker rmi
@MichelMüller when building an image from a dockerfile you can specify the -rm option to remove intermediate containers after a successful build.
@MichelMüller the images are what are used for caching, so removing the containers won't effect that.
If you want to use awk for this consider this command if you want do rm all stopped containers (without a error because of the first line): docker ps -a | awk 'NR > 1 {print $1}' | xargs docker rm
This should be the updated command for removing untagged images docker rmi $(docker images -q -f dangling=true)
C
Community

Another method, which I got from Guillaume J. Charmes (credit where it is due):

docker rm `docker ps --no-trunc -aq`

will remove all containers in an elegant way.

And by Bartosz Bilicki, for Windows:

FOR /f "tokens=*" %i IN ('docker ps -a -q') DO docker rm %i

For PowerShell:

docker rm @(docker ps -aq)

An update with Docker 1.13 (Q4 2016), credit to VonC (later in this thread):

docker system prune will delete ALL unused data (i.e., in order: containers stopped, volumes without containers and images with no containers).

See PR 26108 and commit 86de7c0, which are introducing a few new commands to help facilitate visualizing how much space the Docker daemon data is taking on disk and allowing for easily cleaning up "unneeded" excess.

docker system prune

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N] y

this somehow doesnt work for me, but docker ps -a -q | xargs docker rm works, (sudo may be needed)
what about docker rm $(docker ps -a -q) ?
@qkrijger, this doesn't change anything from your original answer, except for adding bashism. The problem is with command line overflow. xargs variant deals with it in a nice way. I would also add --no-trunk to docker ps to avoid (unlikely) id clashes.
be aware if you use data-only container, it will remove them also
I don't see the point with --no-trunc since docker rm doesn't need full IDs anyway.
P
Peter Mortensen

Updated Answer Use docker system prune or docker container prune now. See VonC's updated answer.

Previous Answer Composing several different hints above, the most elegant way to remove all non-running containers seems to be:

docker rm $(docker ps -q -f status=exited)

-q prints just the container ids (without column headers)

-f allows you to filter your list of printed containers (in this case we are filtering to only show exited containers)


This should be the correct answer because it relies on docker to tell you which containers are no longer used, rather than assuming the text output format of $(docker images) will not change. Bonus points for spawning only one extra process instead of two.
You might want to add -v to avoid dangling volumes: docker rm -v $(docker ps -q -f status=exited). See docs.docker.com/userguide/dockervolumes/… for details about dangling volumes.
@rluba apparently in Docker 1.9 there will be a separate volume api for handling that problem. github.com/docker/docker/pull/14242
an alias might be handy: alias docker-gc="docker rm -v \$(docker ps -q -f status=exited)"
Unlike the answer marked correct, @RyanWalls answer works on OSX as well as being more concise.
P
Peter Mortensen

The official way is:

docker rm `docker ps -aq`

The Docker maintainers have indicated there will be no command for this - and you compose the commands like that:

We have discussed this before and prefer users to use the above line without having to add additional code to Docker.


This is a bad solution though, because it'll also delete storage containers.
What do you mean "storage containers"? If you mean data-only containers which once upon a time were used to keep references to data volumes, those are no longer necessary because of the availability of docker volume subcommand, and named volumes.
Note that this won't work inside Windows Powershell. For that, this is a better solution: stackoverflow.com/a/23674294/1150683
@Sobrique If you don't react, at least you should delete your comment, it is nearly complete and harmful nonsense.
V
VonC

With Docker 1.13 (Q4 2016), you now have:

docker system prune -a will delete ALL unused data (i.e., in order: containers stopped, volumes without containers and images with no containers).

docker system prune without -a will remove (for images) only dangling images, or images without a tag, as commented by smilebomb.

See PR 26108 and commit 86de7c0, which are introducing a few new commands to help facilitate visualizing how much space the Docker daemon data is taking on disk and allowing for easily cleaning up "unneeded" excess.

docker system prune -a

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N] y

As wjv comments,

There is also docker {container,image,volume,network} prune, which may be used to remove unused instances of just one type of object.

Introduced in commit 913e5cb, only for Docker 1.13+.

docker container prune

Thanks for sharing - for this to become visible, I'm quoting you in the answer high up in the thread
As usual, add the -f flag to force the cleanup with no questions asked.
should be marked as the nowdays correct answer, most of the above were right back in time, but are nodays overcomplicated
Agreed, so much easier lately, up up you go!
The description in the code block is for docker system prune -a, which removes unused images. docker system prune only removes dangling images, or images without a tag.
l
levi

UPDATED 2021 (NEWEST)

docker container prune

This - 2017 (OLD) way

To remove ALL STOPPED CONTAINERS

docker rm $(docker ps -a -q)

To remove ALL CONTAINERS (STOPPED AND NON STOPPED)

docker rm  -f $(docker ps -a -q)

downvoted, since this is for sure not the way you do that in 2017 - whis would be docker volume/container/image prune, see stackoverflow.com/a/39860665/3625317
upvoted to counter the downvote because a) this answer was from 2016, and b) plenty of folks dont run the bleeding edge.
unknown shorthand flag: 'a' in -a (Windows10)
we can simply use this to remove containers by using filter option NOTE: until=24h means 24 hours old, you can change it accordingly. >> docker container prune --filter "until=24h"
c
caktux

It is now possible to use filtering with docker ps:

docker rm $(docker ps -q -f status=exited)

And for images:

docker rmi $(docker images -q -f "dangling=true")

However, any of those will cause docker rm or docker rmi to throw an error when there are no matching containers. The older docker rm $(docker ps -aq) trick was even worse as it tried to remove any running container, failing at each one.

Here's a cleaner script to add in your ~/.bashrc or ~/.profile :

# Use `docker-cleanup --dry-run` to see what would be deleted.

function docker-cleanup {
  EXITED=$(docker ps -q -f status=exited)
  DANGLING=$(docker images -q -f "dangling=true")

  if [ "$1" == "--dry-run" ]; then
    echo "==> Would stop containers:"
    echo $EXITED
    echo "==> And images:"
    echo $DANGLING
  else
    if [ -n "$EXITED" ]; then
      docker rm $EXITED
    else
      echo "No containers to remove."
    fi
    if [ -n "$DANGLING" ]; then
      docker rmi $DANGLING
    else
      echo "No images to remove."
    fi
  fi
}

Edit: As noted below, original answer was for removing images, not containers. Updated to answer both, including new links to documentation. Thanks to Adrian (and Ryan's answer) for mentioning the new ps filtering.


Note the real avantage of this - you don't accidentally kill off storage conatiners.
You can also use status=created to get ones that are not running and have never run.
C
Community

Remove all stopped containers:

docker rm $(docker ps -a | grep Exited | awk '{print $1}')

From the comment by pauk960:

Since version 1.3.0 you can use filters with docker ps, instead of grep Exited use docker ps -a -f status=exited. And if you use -q with it you can get container IDs only instead of full output, no need to use awk for that.


K
Konstantin Pereiaslov

If you do not like to remove all containers, you can select all containers created before or after a specific container with docker ps -f before=<container-ID> or with docker ps -f since=<container-ID>

Let's say you have developed your system, and now it is working, but there are a number of containers left. You want to remove containers created before that working version. Determine the ID of the working container with docker ps.

Remove containers created before an other container

docker rm $(docker ps -f before=9c49c11c8d21 -q)

Another example. You have your database already running on a Docker container. You have developed your application to run on another container and now you have a number of unneeded containers.

Remove containers created after a certain container

docker rm $(docker ps -f since=a6ca4661ec7f -q)

Docker stores containers in /var/lib/docker/containers in Ubuntu. I think extra containers do no other harm, but take up disk space.


L
L0j1k

Update: As of Docker version 1.13 (released January 2017), you can issue the following command to clean up stopped containers, unused volumes, dangling images and unused networks:

docker system prune

If you want to insure that you're only deleting containers which have an exited status, use this:

docker ps -aq -f status=exited | xargs docker rm

Similarly, if you're cleaning up docker stuff, you can get rid of untagged, unnamed images in this way:

docker images -q --no-trunc -f dangling=true | xargs docker rmi

P
Peter Mortensen

Here is my docker-cleanup script, which removes untagged containers and images. Please check the source for any updates.

#!/bin/sh
# Cleanup docker files: untagged containers and images.
#
# Use `docker-cleanup -n` for a dry run to see what would be deleted.

untagged_containers() {
  # Print containers using untagged images: $1 is used with awk's print: 0=line, 1=column 1.
  docker ps -a | awk '$2 ~ "[0-9a-f]{12}" {print $'$1'}'
}

untagged_images() {
  # Print untagged images: $1 is used with awk's print: 0=line, 3=column 3.
  # NOTE: intermediate images (via -a) seem to only cause
  # "Error: Conflict, foobarid wasn't deleted" messages.
  # Might be useful sometimes when Docker messed things up?!
  # docker images -a | awk '$1 == "<none>" {print $'$1'}'
  docker images | tail -n +2 | awk '$1 == "<none>" {print $'$1'}'
}

# Dry-run.
if [ "$1" = "-n" ]; then
  echo "=== Containers with uncommitted images: ==="
  untagged_containers 0
  echo

  echo "=== Uncommitted images: ==="
  untagged_images 0

  exit
fi

# Remove containers with untagged images.
echo "Removing containers:" >&2
untagged_containers 1 | xargs --no-run-if-empty docker rm --volumes=true

# Remove untagged images
echo "Removing images:" >&2
untagged_images 3 | xargs --no-run-if-empty docker rmi

Source: https://github.com/blueyed/dotfiles/blob/master/usr/bin/docker-cleanup


@BradMurray Thanks! You might also like these: github.com/blueyed/dotfiles/commit/…
Does not work on OSX because of the xargs --no-run-if-empty option
C
Community

First, stop running containers before attempting to remove them

Remove running containers

docker rm $(docker stop -t=1 $(docker ps -q))

You could use kill instead of stop. In my case I prefer stop since I tend to rerun them vs. creating a new one every time so I try to shut them down nicely.

Note: Trying to stop a container will give you an error:

Error: Impossible to remove a running container, please stop it first

Remove all containers

docker rm $(docker ps -a -q)

B
Bartosz Bilicki

Removing all containers from Windows shell:

FOR /f "tokens=*" %i IN ('docker ps -a -q') DO docker rm %i

I'll include this in my answer since that is first page. Thanks
"from Windows shell"? Do you mean "using the Windows shell (CMD)"?
P
Peter Mortensen

https://github.com/HardySimpson/docker-cleanup

Docker cleanup

A tiny all-in-one shell, which removes:

Containers that not running more than one day ago

Images that don't belong to any remaining container

Intend to run as a crontab job

Feature

It will remove all : images

If the image has multiple repo:tag references to it, it will remove all repo:tag except with running a container. Actually it is a nature of "docker rmi".

Many error message will be show on screen, and you can decide to 2>/dev/null or not

Learn something from docker-gc, and fix its problem (it can not remove image that has mutliple repo:tag)


P
Peter Mortensen

So, personally I recommend doing this as part of your deploy script for both images and containers, keeping only the most recent n containers and images. I tag my Docker images with the same versioning schema I use with git tag as well as always tagging the latest Docker image with "latest." This means that without cleaning up anything, my Docker images wind up looking like:

REPOSITORY              TAG       IMAGE ID        CREATED         VIRTUAL SIZE
some_repo/some_image    0.0.5     8f1a7c7ba93c    23 hours ago    925.4 MB
some_repo/some_image    latest    8f1a7c7ba93c    23 hours ago    925.4 MB
some_repo/some_image    0.0.4     0beabfa514ea    45 hours ago    925.4 MB
some_repo/some_image    0.0.3     54302cd10bf2    6 days ago      978.5 MB
some_repo/some_image    0.0.2     0078b30f3d9a    7 days ago      978.5 MB
some_repo/some_image    0.0.1     sdfgdf0f3d9a    8 days ago      938.5 MB

Now, of course I don't want to keep all my images (or containers) going back to perpetuity on all my production boxes. I just want the last 3 or 4 for rollbacks and to get rid of everything else. Unix's tail is your best friend here. Since docker images and docker ps both order by date, we can just use tail to select all but the top three and remove them:

docker rmi $(docker images -q | tail -n +4)

Run that along with your deploy scripts (or locally) to always keep just enough images to comfortably roll back without taking up too much room or cluttering stuff up with old images.

Personally, I only keep one container on my production box at any time, but you can do the same sort of thing with containers if you want more:

docker rm $(docker ps -aq | tail -n +4)

Finally, in my simplified example we're only dealing with one repository at a time, but if you had more, you can just get a bit more sophisticated with the same idea. Say I just want to keep the last three images from some_repo/some_image. I can just mix in grep and awk and be on my way:

docker rmi $(docker images -a | grep 'some_repo/some_image' | awk '{print $3}' | tail -n +4)

Again, the same idea applies to containers, but you get it by this point so I'll stop giving examples.


P
Peter Mortensen

Use:

docker rm -f $(docker ps -a -q)

It forcefully stops and removes all containers present locally.


Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". We make an effort here to be a resource for knowledge.
In ubuntu 16.04, docker requires sudo, so you have to write sudo docker rm -f $(sudo docker ps -a -q).
as a plus, this also works in Windows under powershell!
@Elliott I think sudo is required everywhere unless you add your user to the 'docker' group. I use ubuntu 16.10 without sudo by adding my user to the docker group.
P
Pithikos

Remove 5 oldest containers:

docker rm `docker ps -aq | tail -n 5`

See how many containers there are left:

docker ps -aq | wc -l

Nice Job @Pithikos. I have added the answer that removes all the old containers.
R
Ric_Harvey

Remove all stopped containers.

sudo docker rm $(sudo docker ps -a -q)

This will remove all stopped containers by getting a list of all containers with docker ps -a -q and passing their ids to docker rm. This should not remove any running containers, and it will tell you it can’t remove a running image.

Remove all untagged images

Now you want to clean up old images to save some space.

sudo docker rmi $(sudo docker images -q --filter "dangling=true")


Don't forget to delete docker volumes by specifying the -v option (sudo docker rm -v $(sudo docker ps -a -q))
Didn't look this up, but I guess the same as: docker ps -aq | xargs docker rm -v
This only works on Linux, not Windows... But docker rm -f $(docker ps -a -q) works in PowerShell / Docker for Windows.
f
f-society

New way: spotify/docker-gc play the trick.

 docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc spotify/docker-gc

Containers that exited more than an hour ago are removed.

Images that don't belong to any remaining container after that are removed

It has supported environmental settings

Forcing deletion of images that have multiple tags

 FORCE_IMAGE_REMOVAL=1

Forcing deletion of containers

 FORCE_CONTAINER_REMOVAL=1 

Excluding Recently Exited Containers and Images From Garbage Collection

 GRACE_PERIOD_SECONDS=86400

This setting also prevents the removal of images that have been created less than GRACE_PERIOD_SECONDS seconds ago.

Dry run

 DRY_RUN=1

Cleaning up orphaned container volumes CLEAN_UP_VOLUMES=1

Reference: docker-gc

Old way to do:

delete old, non-running containers

 docker ps -a -q -f status=exited | xargs --no-run-if-empty docker rm
             OR 
 docker rm $(docker ps -a -q)

delete all images associated with non-running docker containers

 docker images -q | xargs --no-run-if-empty docker rmi

cleanup orphaned docker volumes for docker version 1.10.x and above

 docker volume ls -qf dangling=true | xargs -r docker volume rm

Based on time period

 docker ps -a | grep "weeks ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm
 docker ps -a | grep "days ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm
 docker ps -a | grep "hours ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm

Interesting alternative. +1
P
Peter Mortensen

Remove all docker processes: docker rm $(docker ps -a -q) Remove specific container: $ docker ps -a (lists all old containers) $ docker rm container-Id


P
Peter Mortensen

You can use the following command to remove the exited containers:

docker rm $(sudo docker ps -a | grep Exit | cut -d ' ' -f 1)

Here is the full gist to also remove the old images on docker: Gist to remove old Docker containers and images.


m
mckoss
#!/bin/bash
# docker-gc --- Remove stopped docker containers

RUNNING=$(docker ps -q)
ALL=$(docker ps -a -q)

for container in $ALL ; do
    [[ "$RUNNING" =~ "$container" ]] && continue
    echo Removing container: $(docker rm $container)
done

for those that don't want to search for it themselves github.com/spotify/docker-gc
It's perfect. I have also write an answer that has the same functionality.
M
Marcin Szymczak

You can remove only stopped containers. Stop all of them in the beginning

docker stop $(docker ps -a -q)

Then you can remove

docker rm $(docker ps -a -q)


P
Peter Mortensen

I always use docker rmi $(docker ps -a -q) to remove all images.

You can remove directory /var/lib/docker/graph when docker rmi failed.


Thanks for adding the /var/lib/docker/graph info
The questions was how to remove containers, not images.
C
Community

The basic steps to stop/remove all containers and images

List all the containers docker ps -aq Stop all running containers docker stop $(docker ps -aq) Remove all containers docker rm $(docker ps -aq) Remove all images docker rmi $(docker images -q)

Note: First you have to stop all the running containers before you remove them. Also before removing an image, you have to stop and remove its dependent container(s).


S
Sijo M Cyril

I am using following commands to delete Exited and Restarting docker containers

docker stop --force $(docker ps -a|grep Exited| awk '{print $1}')
docker rm --force $(docker ps -a|grep Exited| awk '{print $1}')
docker stop --force $(docker ps -a|grep Restarting| awk '{print $1}')
docker rm --force $(docker ps -a|grep Restarting| awk '{print $1}')

Using below command to remove images named as none

docker image rm --force $(docker image ls  |grep none |awk '{print $3}')

P
Pal

Try this command to clean containers and dangling images.

docker system prune -a

This is an amazing pro-tip!
e
edencorbin

I wanted to add this simple answer as I didn't see it, and the question is specifically "old" not "all".

sudo docker container prune --filter "until=24h"

Adjust the 24h for whatever time span you want to remove containers that are older than.


K
Kraig McConaghy

For anyone interested, I took the example from qkrijger and turned it into a clear all (stop and remove all)

docker stop `docker ps --no-trunc -aq` ; docker rm `docker ps --no-trunc -aq`

If you are removing the containers anyway, then docker rm -f $(docker ps --no-trunc -aq) is faster
True, but if you need it to go through proper shutdown to cleanup shared or reused resources (i.e. Attached volumes, correctly closed active connections, etc) then you need to call stop first. Great example, if you have a Jenkins container, then killing the container is a bad idea. You want it to save any unpersisted changes, warn logged in users, and, very importantly, properly stop all builds.
agreed, that is a very valid use case
P
Peter Mortensen

To simply remove everything that is not currently used by a running container the following alias, that I usually put into the .bash_profile on my Mac, will help:

alias dockerclean="docker ps -q -a | xargs docker rm -v && docker images -q | xargs docker rmi"

Whenever dockerclean is invoked from the command line it will remove stopped containers as well as unused image layers. For running containers and used images it will print a warning message and skip over it.