- What Docker objects need clean up
- Clean up Docker containers
- Cleaning Docker images
- Cleaning Docker volumes
- Clean up Docker networks
- Clean up your system
Working with Docker, you’ll soon find various objects on your system that are hanging around from previous activities. It is essential to learn how to clean up Docker objects safely and pragmatically during project work.
You can watch this tutorial on Youtube, too.
What Docker objects need clean up
The Docker objects that stay around may be of various types:
- Docker containers
- Docker images
- Docker volumes
- Docker networks
Clean up Docker containers
Docker will not clean up stopped containers by default. Containers may exit with a success exit code or with an error, and they may be stopped by you. In all these cases the containers will remain on your system and you’ll want to clean them up after a while.
Before we move to the cleaning instructions, let me give you a few tips to remove containers as part of your workflow:
- Starting your Docker containers with
docker container run --rmtells Docker to remove the container when it exits. The downside of this method is that you’ll not be able to access the Docker logs after the container exits.
- Starting your containers with
docker-compose upand stopping them with
docker-compose downwhen you finished your activities, will remove all containers and networks involved with the application automatically. This is good practice because the logs will be available all along and cleanup is built into the workflow. Using Docker Compose will leave less garbage on the system.
- Using Swarm mode’s
docker service createor
docker stack deployto create containers and
docker service rmor
docker stack rmwill remove containers automatically. Your workflow and benefits are similar to Docker Compose.
After a while we all have something to clean up, so let’s see how to do this. I started up a few Docker containers on my machine:
~ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b805f67ec113 nginx:1.15.1-alpine "nginx -g 'daemon of…" 13 seconds ago Up 11 seconds 0.0.0.0:8080->80/tcp hardcore_archimedes 8cfa08b910f6 nginx:1.15.1-alpine "-d" 38 seconds ago Created 0.0.0.0:8080->80/tcp romantic_elbakyan 3edccda81c16 takacsmark/takacsmark-dot-com:devtools-10.8.0-stretch "/bin/bash" 19 hours ago Exited (0) 18 hours ago takacsmarkgithubio_gulp_run_1 df2c60b675f1 jekyll/jekyll:3.8.3 "/usr/jekyll/bin/ent…" 19 hours ago Up 19 hours 0.0.0.0:4000->4000/tcp, 0.0.0.0:35729->35729/tcp takacsmark-dot-com
I have 4 Docker containers on the list:
- 2 Nginx containers. Please note that one of the Nginx containers is running (it’s in the “Up” state) and the other container is in “Created” state. The created state means that the container was created but it’s not running.
- I have a container based on a custom Docker image called
takacsmark/takacsmark-dot-com:devtools-10.8.0-stretch. I use this image to run gulp tasks when I build my blog. This container was created with
docker compose runand it is in the “Exited” state now.
- I have another container called
takacsmark-dot-comthat serves my blog in development mode. This container was started with Docker Compose.
We can clean up the containers with the
docker container prune command. Docker will focus on the containers only, it won’t matter which way you started them. The command will remove all stopped containers.
Let’s see how it works:
~ docker container prune WARNING! This will remove all stopped containers. Are you sure you want to continue? [y/N] y Deleted Containers: a3586090a7ac9647a6170e0e4ea5ac495918373b245af1dab6e88ec5e202c928 8cfa08b910f6cc61001426f4ce00de50a030b62bcb34975999dd19e23c918820 Total reclaimed space: 5B
This command will ask for confirmation (that you can suppress with the
-f flag). It has removed two Docker containers from my machine. As you can see in the output, Docker has removed 2 containers and the amount of total reclaimed space is also displayed.
This is the list of containers now:
~ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b805f67ec113 nginx:1.15.1-alpine "nginx -g 'daemon of…" About an hour ago Up About an hour 0.0.0.0:8080->80/tcp hardcore_archimedes df2c60b675f1 jekyll/jekyll:3.8.3 "/usr/jekyll/bin/ent…" 20 hours ago Up 20 hours 0.0.0.0:4000->4000/tcp, 0.0.0.0:35729->35729/tcp takacsmark-dot-com
As you can see the containers in “Exited” or “Created” state were removed from my system.
You can use
docker container prune in a bit more sophisticated way with filters. You can, for example, remove containers created more than 10 hours ago like this:
~ docker container prune --force --filter "until=10h"
Get more help with the command
docker container prune --help.
Cleaning Docker images
Yyou can use
docker image prune to cleaning up Docker images in two modes:
- Clean up dangling images. - This is the default behavior.
- Clean up all Docker images that have no running containers associated with them.
Cleaning dangling images
Dangling images are the images that are not tagged on your system. They are created when you build a Docker image with the same tag again and again. In this case Docker will move the tag to the latest image resulting from the build and all previous images created by that build will have no tag.
Here is an example:
~ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE takacsmark/flask-redis 1.0 027a4f101492 2 seconds ago 88.2MB <none> <none> 74ebf583f7b3 About a minute ago 88.2MB takacsmark/flask-redis <none> 7c94cfc2fcd5 5 days ago 88.2MB
These images are the result of the same build process, but they have been built at different times and they incorporate project changes, so they are different. Only one of them has a proper tag, the other two are dangling.
You can list dangling images on your system with this command:
~ docker image ls -f "dangling=true"
You can prune dangling images with the
docker image prune command:
~ docker image prune WARNING! This will remove all dangling images. Are you sure you want to continue? [y/N] y Deleted Images: deleted: sha256:74ebf583f7b37c6ab2e15a72c6b47f7ba508c0b5a206df087574a91269193157 deleted: sha256:d143fb78b3a0618e934dcbda2b1132432fdc463705a752d24d6e46a4a93603b0 deleted: sha256:b733b700e67275d0f3c697118033196f92c1c47f78e5b730cae3536b385a243e deleted: sha256:77899bf89c610b150eb69069177d08e1a4254141b2229bd12f04062b1886c129 untagged: takacsmark/[email protected]:24f3a64f803558336d214b0d72367e7b22777f61967bb0a9754f507b24ef8dc9 deleted: sha256:7c94cfc2fcd548208ec003b99581fb7fdcc0fda86c5acfca6fb62432de634a5c deleted: sha256:99433c6f5ec4307e3931af82eae6d51d85422f2cc49511d851ec08eb1f6cc061 deleted: sha256:904ba7062c986684394f48cffd1fc43f9d6db3bfecc5891d1ec338091d7924e8 deleted: sha256:a5584c56e7347c6a67570c09a1940ec7030641b5dd4ffaf7ee68c2f8ee819b77 Total reclaimed space: 14.59kB
Both images were cleaned from my system with all layers associated with them. The reclaimed space is not significant right now, but it can be quite important if you build large images.
Cleaning all Docker images
You can use the command
docker image prune -a or
docker image prune --all to remove all unused images from your system. I never used this command, to be honest, I like a bit more control over what I clean up.
You can use the
-filter option with
docker image prune, too, and you can get more information using the command
docker image prune --help.
Cleaning Docker volumes
Docker volumes are not removed by Docker by default, because Docker volumes contain data, and you should be in control of your data at all times. So, if you stop a container, the related volumes will hang around on your system.
If you list the Docker volumes on your machine, you might be surprised:
~ docker volume ls DRIVER VOLUME NAME local 4760c2d78bf6de835421aed7a2dba9a3b401d874af9ccc2bf608e0d785718f1a local 68968027bb09ffaad6a2d8c6e95e3019e14142d2fca49a4a15784162b04611dd local 69acecb345cbc93109bbcbee27c0159bd74cdaae52feef8cbefba1b3508a25df local flask-redis_mydata local wordpress-official_mariadbdata local wordpress-official_wordpressdata
You’ll find that you have the named volumes that you created on your system, like
wordpress-official_mariadbdata on my list.
You’ll also have volumes with random long names. These volumes are created automatically by Docker. Most often they are created because they are defined in Docker images. Many official images define Docker volumes to store data externally. These volumes will be created, even if you do not specify any volume information when you start up your containers. In this case such volumes get a random name.
The official Mariadb image defines a volume in the Dockerfile that points to
/var/lib/mysql, for example. The official Postgres Dockerfile defines an image that points to
/var/lib/postgresql/data. This means that if you start up a container from these images, Docker will create a volume with a random name and put the data under the specific directory into that volume.
You may accumulate quite many Docker volumes on your system over time. It’s a good practice to check and clean your volumes regularly.
Cleaning Docker volumes is critical during development. It happens often that the data in your named volumes will give you bugs when you run updated code on the old version of your data. You should build volume pruning into your workflow.
docker volume prune command will remove all volumes that are not used by at least one container. This may get dangerous, because you may loose some prepared data. Therefore it is essential to set up REPEATABLE data initiation and migration tools for your projects, don’t just store critical data in your Docker volumes.
~ docker volume prune WARNING! This will remove all local volumes not used by at least one container. Are you sure you want to continue? [y/N] y Deleted Volumes: 4760c2d78bf6de835421aed7a2dba9a3b401d874af9ccc2bf608e0d785718f1a 68968027bb09ffaad6a2d8c6e95e3019e14142d2fca49a4a15784162b04611dd 69acecb345cbc93109bbcbee27c0159bd74cdaae52feef8cbefba1b3508a25df flask-redis_mydata wordpress-official_mariadbdata wordpress-official_wordpressdata Total reclaimed space: 146MB
The command has removed all volumes form my machine.
The official documentation suggest to use labels to keep some of your volumes and use a prune command like
docker volume prune --filter "label!=keep". I would advice against this practice, because it will not stop anyone from running a
docker volume prune on your system.
You can get more help with the command
docker volume prune --help.
Clean up Docker networks
Docker networks are usually created in a larger context with Docker Compose or in Swarm mode, and you usually use these tools to remove the stacks that will remove networks automatically. Unused networks tend to hang around less often than images or volumes, at least this is my experience.
Nonetheless, you may crate networks with
docker netwrok create or you may end up with unused networks, so let’s see how to clean them.
These are the Docker networks on my machine now:
~ docker network ls NETWORK ID NAME DRIVER SCOPE adb3e03409a4 bridge bridge local cef4092fbf4c docker_gwbridge bridge local b14410585a68 host host local nwmxlht20wbe ingress overlay swarm 6f7f82dc82cd none null local aed6eb1a783e takacsmarkgithubio_default bridge local
The first 5 networks are default networks;
none are the default networks created by the Docker Engine and
docker_gwbridge are created by the Swarm mode. I turned on Swarm mode to show you what happens to these networks.
The last Docker network is custom and it is not used by containers.
If I clean them, the custom network will be removed:
~ docker network prune WARNING! This will remove all networks not used by at least one container. Are you sure you want to continue? [y/N] y Deleted Networks: takacsmarkgithubio_default
You can get more help with
docker network prune --help.
Clean up your system
There is one command to rule them all; you can clean up your entire system with
docker system prune:
- stopped containers
- unused networks
- dangling images
- build cache
The command will not clean up volumes by default, you can use the
docker system prune --volumes command to include volumes in to the cleanup.
You can add the
--all flag to clean up all images, not just dangling ones. Filters are also available, similarly to the previous prune commands.
You can get more information with
docker system prune --help.