Ryan Davidson

@ryanwhocodes

Clean out your Docker images, containers and volumes with single commands

While Docker has commands for stopping and removing images, containers, networks and volumes, they are not comprehensive. Clean out and refresh your entire Docker environment with this set of instructions and set them as shell aliases.

This post explains how to:

  • Find out the Docker data and processes that exist on your system
  • Remove unused Docker images, containers, volumes and networks
  • Remove all for a completely fresh Docker environment
  • How to reuse these commands easily with shell aliases
Docker glossary
- image: a read-only template with instructions for creating a Docker container
- container: a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI
- volume: persists data generated by and used by Docker containers
- dangling: unused image or volume
- network: connects Docker containers and services

List Docker processes and data

A helpful starting point is to see the list of loaded docker elements on your system.

Just clean out unused data and processes

The main difference with cleaning out your Docker environment is whether you want a complete refresh or just to prune it.

Docker provides a convenient method to remove unused containers, networks, and images:

docker system prune

WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all dangling images
        - all build cache
By default, volumes are not removed to prevent important data from being deleted if there is currently no container using the volume. Use the --volumes flag when running the command to prune volumes as well
 — Docker docs: system prune

So, to also remove the volumes (--volumes), any unused images (--all), as well as override the confirmation prompt (--force):

docker system prune --all --force --volumes

WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all volumes not used by at least one container
        - all images without at least one container associated to them
        - all build cache

prune can also be used on just one aspect:

  • docker container prune # Remove all stopped containers
  • docker volume prune # Remove all unused volumes
  • docker image prune # Remove unused images
Photo by Cibi Chakravarthi on Unsplash

Destroy all for a complete Docker refresh

The last command above will not remove all running containers. So for a complete system refresh you need to stop all containers, then run the system prune command.

Fortunately, docker’s stop containers command is just docker container stop [CONTAINERS...]

However, to get the right information for that command, you need to get a list of all container IDs.

docker container ls -aq

ls lists the containers

--all / -a all containers (default shows just running)

--quiet / -q only display numeric IDs

So to pass the return value of this command, the IDs of all containers, to docker stop, you need to wrap it in $().

Command substitution allows the output of a command to be substituted in place of the command name itself. $(command)
 — StackExchange: Unix & Linux — Have backticks (i.e. `cmd`) in *sh shells been deprecated?

The full command for stopping all docker containers is now:

docker container stop $(docker container ls -a -q)

A complete Docker system clean can now be achieved by linking this with the full prune command covered earlier in this post.

docker container stop $(docker container ls -a -q) && docker system prune -a -f --volumes

Similarly, you now know how to combine docker commands to just remove one aspect if you prefer. Pass a list of all the IDs to the associated remove command.

  • Containers docker container rm $(docker container ls -a -q)
  • Images docker image rm $(docker image ls -a -q)
  • Volumes docker volume rm $(docker volume ls -q)
  • Networks docker network rm $(docker network ls -q)

NOTE: There are alternative methods for doing this, for example docker ps for listing running containers, and docker rm for removing containers. I have written it this way as I feel it is more memorable to use consistent command names and syntax across docker objects.

How to reuse them easily with shell aliases

Instead of typing these out each time you can set them as aliases for your shell. You can call the commands whatever you like, here I have called them docker-clean.

alias docker-clean-unused='docker system prune --all --force --volumes'
alias docker-clean-all='docker stop $(docker container ls -a -q) && docker system prune -a -f --volumes'

To set them to load up when you run your shell, add them to your shell’s rc file.

echo [ALIASES...] \ 
>> ~/.bashrc

Then reload the file with the new aliases.

source ~/.bashrc

The full command for bash:

echo "alias docker-clean-unused='docker system prune --all --force --volumes'
alias docker-clean-all='docker container stop $(docker container ls -a -q) && docker system prune -a -f --volumes'" \
>> ~/.bashrc && source ~/.bashrc

The full command for Zsh:

echo "alias docker-clean-unused='docker system prune --all --force --volumes'
alias docker-clean-all='docker container stop $(docker container ls -a -q) && docker system prune -a -f --volumes'" \
>> ~/.zshrc && source ~/.zshrc

Now try the alias commands out in your terminal!

MacBook-Pro% docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                                                                                        NAMES
7087fe30f52d        rabbitmq:3.7.3-management   "docker-entrypoint..."   4 minutes ago       Up 4 minutes        4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp   docker_rabbit_1
MacBook-Pro% docker-clean-all
7087fe30f52d
Deleted Containers:
7087fe30f52dbf84568f3429c52c8b24e335ff5f024a4d3f394f2eef7f0976c6
Deleted Networks:
docker_default
Deleted Volumes:
8c295273aca8a97bfe993fddbb9c0d4f66f7e81c8d8c625adbd0893d4b4a2847
Deleted Images:
untagged: rabbitmq:3.7.3-management
untagged: rabbitmq@sha256:0f681f18d80b2979596e8b262d06cacf7948e924d7f3a67e89be5fdea82cd116
deleted: sha256:2f415b0e9a6e74486edbc01ed99713225f6e65d31256819120319137c280c840
deleted: sha256:bcbbeee6343a0f57576e7c3f67dfa992c11d0e24d916e998dec5eb17c3e180f6
...
Total reclaimed space: 155.1MB

The first time I did this I reclaimed 22GB of space!

Having these commands make it quick and easy to manage your docker system. Now you know how to list and remove things in docker, why not create other aliases, for example just for cleaning out containers:

alias docker-clean-containers='docker container stop $(docker container ls -a -q) && docker container rm $(docker container ls -a -q)'

Read more from Ryan Davidson

Read more from Medium

Read more from the web

Docker - Hacker Noon

More by Ryan Davidson

Topics of interest

More Related Stories