Quick Links

Docker lets you quickly package your applications as containers, making it possible to run them anywhere from your laptop to a public cloud. After using Docker for a while, you can accumulate a large number of redundant containers, images and other resources. Here's how to tidy them up.

Docker doesn't usually delete anything unless you tell it to. That means images you've pulled and containers you've created are probably still hanging around on your system, even if they're no longer used.

Having too many redundant resources can quickly lead to excessive disk usage. It also results in much lengthier output when listing resources on the command line, making it harder to find the information you're looking for.

Pruning Dangling Resources

A "dangling" resource is any Docker object not currently associated with a container. This includes Docker images, networks and volumes, as well as stopped containers. In the case of images, an image is "dangling" if it's untagged and has no references.

Docker provides a single housekeeping command to let you purge all dangling resources and stopped containers. Unless a resource is used by a running container, it will be deleted.

        docker system prune
    

Running the command displays a confirmation prompt which lists the resource types to delete. Type y and press Enter to continue with the deletion. You can disable the confirmation by passing the -f or --force flag.

Screenshot of docker system prune command

Volumes aren't removed by default. Deleting volumes risks the loss of persistent data which you might want to keep. If you do want to remove volumes which aren't associated with a container, pass the --volumes flag to include them in the operation.

You can delete even more image data by passing the -a (or --all) flag. This will cause Docker to delete all unused images, not just dangling unreferenced ones. Each image on your system will be deleted, unless there's at least one running container that requires it.

Using Filters When Pruning

Filters can be used with the prune command. Filtering gives you more control over what gets deleted. Two filters are currently supported, until and timestamp.

  • until - The until filter prevents the deletion of containers, images and networks created before a given time. You can specify the time in several different formats, such as a Unix timestamp in seconds (e.g. 1614890000) or a date formatted timestamp string (e.g. 2021-03-04T20:30:00).
  • label - The label filter constrains the deletion so only resources with a given label are deleted. Labels can be used with containers, images, networks and volumes. You specify labels as either label=key=value (key equal to value), label!=key=value (key not equal to value), label=key (has the given label) or label!=key (does not have the given label).

To use a filter, pass it to the --filter flag:

        docker system prune --filter until=2021-03-04T20:30:00 --filter label=foo=bar
    

This command would delete resources with the foo=bar label that were created before 8:30pm on March 4th. Any resources not matching this criteria would be left untouched.

Pruning Individual Resource Types

You won't always need to use docker system prune. Docker provides more granular pruning commands too. These can be used when you only want to remove one type of resource.

The --force and --filter flags supported by docker system prune also apply to the individual prune commands listed below.

Pruning Containers

Day-to-day Docker commands can quickly result in a large number of stopped containers. The problem is exasperated if you docker build images without the --rm flag, as this causes intermediary build layers to be retained.

Screenshot of docker ps output

Run docker container prune to clean up stopped containers. Stopped containers don't appear when you run docker ps; to see them, you'll need to use docker ps -a to show all the containers on your system.

If you want to remove an individual container, use the docker rm command passing the container's ID. You can get this by running docker ps. If the container is running, you'll need to use the --force flag to delete it.

Pruning Images

Use docker image prune to remove all dangling images. Like docker system prune, this will affect images that are either untagged or are not referenced by any container.

Add the -a flag to instead delete all unused images. This will purge every image on your system that's not required by at least one container. Tagged images will be included too, letting you quickly clear up old pulls from Docker Hub.

You can remove a specific image with the docker rmi command:

        docker rmi wordpress:latest
    

When one image has multiple tags, docker rmi will remove the given tag without actually deleting the image. It will be deleted once the last tag has been removed.

Pruning Networks

Docker networks aren't cleaned automatically. Over time, you can end up with a large number of them. This clutters your system with redundant virtual bridge devices and routing table entries. Run docker network prune to destroy any unused networks and revert the changes to your host's configuration.

You can delete individual networks by running docker rm my-network.

Pruning Volumes

Docker will never delete a volume. They store the persistent data created by your containers so unintended removal could have devastating consequences. Volumes may also be shared by multiple containers or left dormant ready to attach to another container in the future.

If you want to prune unused volumes, you should run docker volume prune. This will delete any volumes which aren't used by at least one container. Individual volumes can be removed using docker volume rm my-volume.

Preventing Future Accumulation

You can minimise the risk of redundant resources piling up in the future by taking care to pass the --rm flag to docker build and docker run commands.

When used with build, it will cause the deletion of intermediary build layers (marked as <none>:<none> in docker images) output. This can represent a significant reduction in disk usage. A new intermediary layer is normally created for each instruction in your Dockerfile. You can usually remove them unless you intend to use them later as the starting point for a new image.

Using --rm with docker run will remove the container as soon as its command exits. This is ideal when running a binary in a single-use container. Don't pass --rm to containers you intend to run perpetually, or that you might want to start and stop on-demand. Examples include web and database servers that run a service instead of a user-supplied command.

Conclusion

Pruning your Docker resources can free up disk space and help you work with the Docker CLI. Eliminating redundant containers and images makes it easier to identity the resources you're looking for.

Docker won't delete anything unless you tell it to. It's worth running docker system prune periodically to keep your system clean. You could create a cron task that runs it monthly, using the until filter to create a retention period for recently added resources.