It seems like every time we have a new application, there’s a need to clean or remove some piece of electronic garbage we may have left behind! In this short tutorial, we’ll discuss some techniques for cleaning up after ourselves in the Docker world. Since our previous tutorials have worked with both Docker and Docker Compose, we’ll take a look at different cleanup commands for both.
Cleaning up: Docker
During rapid prototyping and code development, it can be easy to think that a container is closed and/or removed, when in fact it still exists. This can become problematic since a container that is not removed may still be the reason why a network is still being used or a volume is still perceived as active. The fact is, containers need to be kept in check.
Of course, this whole process starts with understanding which containers are active or which containers exist. This can be handled using either list (
ls) or process status (
ps); both will return the same information (container ID, image name, time created, status, ports, and names).
# Check for running / existing containers docker container ls # List Docker containers docker ps
Once we know the container names, though, stopping the containers and removing them is straightforward. While the
rm command will remove one or more named containers,
prune removes all stopped containers. Note that the command
docker container stop also has an additional flag,
-t; this is the amount of time Docker should wait before killing the container (the default is 10 seconds).
# Stop a Docker container docker stop <CONTAINER> # -or- docker container stop <CONTAINER> # Remove one or more specific containers docker container rm <CONTAINER1> <CONTAINER2> ... # Remove all stopped containers docker container prune
If you recall during our first few tutorials, we built a simple container. Based off of the container, we tasked Docker with compiling the container into an image. We could then access that image and poke around the folder structure. But how do you delete an image you no longer need?
# Check for running / existing images docker image ls # Delete the image docker image rm <image>:<tag>
Volumes are attached to containers, and you cannot remove a volume without first stopping the container it is attached to! Nevertheless, once all containers are stopped the existing volumes can be identified using the list (ls) command:
# Check for running / existing volumes docker volume ls # Gather detailed information about a volume docker volume inspect <VOLUME>
Once the specific volumes are identified, they can be removed (
rm) individually. Alternatively, all unused local volumes can be simultaneously removed using
prune. Again, the volumes must be unused before being destroyed!
# Remove one or more specific volumes docker volume rm <VOLUME1> <VOLUME2> ... # Remove all unused local volumes docker volume prune
Similar to volumes, networks must be either unused or detached from a container before they can be destroyed. Fortunately, we can find and inspect networks the same way we would find and inspect volumes by using list (
ls) or inspect (
inspect). Alternatively, we can disconnect a specific container from a network.
# Check for running / existing networks docker network ls # Gather detailed information about a network docker network inspect <NETWORK> # Disconnect a container from a network docker network disconnect <NETWORK> <CONTAINER>
Once the offending networks have been disconnected and identified, they can be destroyed individually using remove (
rm) or en masse (
# Remove one or more specific networks docker network rm <NETWORK1> <NETWORK2> ... # Remove all unused networks docker network prune
Of course, Docker has a method to do remove all unused objects (or at least most of them) in one swift motion. This command is system prune, which removes all unused data including stopped containers, networks not being used by at least one container, dangling images, and dangling build caches.
# Remove all unused data docker system prune
So why not volumes? Imagine you copied in data from a local repository into a shared volume drive. In the process, you’d generated two containers, and each container had a specific method of processing the data. After both containers have completed their jobs, you have no need for the containers or network that connected them, but you still want to keep the processed data! This is one of the valuable reasons why docker system prune elects to not remove volumes by default. You can, however, tell Docker to remove volumes as well during its system prune, using the
Cleaning up: Docker Compose
As we’ve seen in the past tutorials, Docker Compose and Docker are very similar in nature. This makes sense, since Docker Compose is built to automatically compile and run Docker files. It makes sense, then, that they use a similar command structure. Assuming a Docker Compose file has already been spun up, it can be stopped and its containers either listed or killed:
# Stop and remove resources from Docker Compose instance docker-compose down # Stop services within Docker Compose instance docker-compose stop # List containers in Docker Compose instance docker-compose ps # Kill containers from Docker Compose instance docker-compose kill
Again, it’s worth noting that many of these functions have additional flags to modify functionality. For instance, docker-compose down has an
--rmi <type> flag, which removes images from the Docker Compose instance, where
<type> can either be “all”, “local”, or custom. The
-v) flag removes named volumes,
--remove-orphans removes containers for services not defined in the Docker Compose file, and
-t) specifies a length of time to wait before killing the process altogether.
In this tutorial, we’ve walked through a number of ways to stop, kill, and clean unused containers, networks, and volumes within both Docker and Docker Compose. Although we did not walk through specific examples, we’ll not doubt continue using them as we progress through the tutorial series.
The bottom line, though, is that keeping your Docker workspace and your Compose workspace clean are enormously advantageous when troubleshooting or developing new Docker or Compose files and functionality. Not being able to delete a volume because it’s being “used” by a container you’ve forgotten about is incredibly frustrating! Hopefully these commands will help you on your way.
Now onto the fun topics: automatically running scripts within a container! As usual, thank you for stopping by, your support and attention mean a great deal to me! If you find this content interesting and helpful, please feel free to Like, comment, or subscribe!
Get new content delivered directly to your inbox.