How to remove old and unused Docker images
(original answer see below)
Update Sept. 2016: Docker 1.13: PR 26108 and commit 86de7c0 introduce 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
will delete ALL dangling data (i.e. In order: containers stopped, volumes without containers and images with no containers). Even unused data, with -a
option.
You also have:
docker container prune
docker image prune
docker network prune
docker volume prune
For unused images, use docker image prune -a
(for removing dangling and ununsed images).
Warning: 'unused' means "images not referenced by any container": be careful before using -a
.
As illustrated in A L's answer, docker system prune --all
will remove all unused images not just dangling ones... which can be a bit too much.
Combining docker xxx prune
with the --filter
option can be a great way to limit the pruning (docker SDK API 1.28 minimum, so docker 17.04+)
The currently supported filters are:
until (<timestamp>)
- only remove containers, images, and networks created before given timestamplabel
(label=<key>
,label=<key>=<value>
,label!=<key>
, orlabel!=<key>=<value>
) - only remove containers, images, networks, and volumes with (or without, in caselabel!=...
is used) the specified labels.
See "Prune images" for an example.
Original answer (Sep. 2016)
I usually do:
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
I have an [alias for removing those dangling images: drmi
]13
The
dangling=true
filter finds unused images
That way, any intermediate image no longer referenced by a labelled image is removed.
I do the same first for exited processes (containers)
alias drmae='docker rm $(docker ps -qa --no-trunc --filter "status=exited")'
As haridsv points out in the comments:
Technically, you should first clean up containers before cleaning up images, as this will catch more dangling images and less errors.
Jess Frazelle (jfrazelle) has the bashrc function:
dcleanup(){
docker rm -v $(docker ps --filter status=exited -q 2>/dev/null) 2>/dev/null
docker rmi $(docker images --filter dangling=true -q 2>/dev/null) 2>/dev/null
}
To remove old images, and not just "unreferenced-dangling" images, you can consider docker-gc
:
A simple Docker container and image garbage collection script.
- Containers that exited more than an hour ago are removed.
- Images that don't belong to any remaining container after that are removed.
Update the second (2017-07-08)
Refer (again) to VonC, using the even more recent system prune
. The impatient can skip the prompt with the -f, --force
option:
docker system prune -f
The impatient and reckless can additionally remove "unused images not just the dangling ones" with the -a, --all
option:
docker system prune -af
https://docs.docker.com/engine/reference/commandline/system_prune/
Update
Refer to VonC's answer which uses the recently added prune
commands. Here is the corresponding shell alias convenience:
alias docker-clean=' \
docker container prune -f ; \
docker image prune -f ; \
docker network prune -f ; \
docker volume prune -f '
Old answer
Delete stopped (exited) containers:
$ docker ps --no-trunc -aqf "status=exited" | xargs docker rm
Delete unused (dangling) images:
$ docker images --no-trunc -aqf "dangling=true" | xargs docker rmi
If you have exercised extreme caution with regard to irrevocable data loss, then you can delete unused (dangling) volumes (v1.9 and up):
$ docker volume ls -qf "dangling=true" | xargs docker volume rm
Here they are in a convenient shell alias:
alias docker-clean=' \
docker ps --no-trunc -aqf "status=exited" | xargs docker rm ; \
docker images --no-trunc -aqf "dangling=true" | xargs docker rmi ; \
docker volume ls -qf "dangling=true" | xargs docker volume rm'
References
docker ps -f
docker rm
docker images -f
docker rmi
- Docker v1.9.0 release notes
docker volume ls
docker volume rm
The other answers are great, specifically:
docker system prune # doesn't clean out old images
docker system prune --all # cleans out too much
But I needed something in the middle of the two commands so the filter
option was what I needed:
docker image prune --all --filter "until=4320h" # delete images older than 6 months ago; 4320h = 24 hour/day * 30 days/month * 6 months
Hope that helps :)
For reference: https://docs.docker.com/config/pruning/#prune-images
To remove old tagged images that are more than a month old:
$ docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' \
| grep ' months' | awk '{ print $1 }' \
| xargs --no-run-if-empty docker rmi
Note that it'll fail to remove images that are used by a container, referenced in a repository, has dependent child images... which is probably what you want. Else just add -f
flag.
Example of /etc/cron.daily/docker-gc
script:
#!/bin/sh -e
# Delete all stopped containers (including data-only containers).
docker ps -a -q --no-trunc --filter "status=exited" | xargs --no-run-if-empty docker rm -v
# Delete all tagged images more than a month old
# (will fail to remove images still used).
docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' | grep ' months' | awk '{ print $1 }' | xargs --no-run-if-empty docker rmi || true
# Delete all 'untagged/dangling' (<none>) images
# Those are used for Docker caching mechanism.
docker images -q --no-trunc --filter dangling=true | xargs --no-run-if-empty docker rmi
# Delete all dangling volumes.
docker volume ls -qf dangling=true | xargs --no-run-if-empty docker volume rm