How to Prune Docker Images Automatically with a Daily Cron job

Learn how to automatically prune unused Docker images, networks and volumes on a daily basis with a Cron job to ensure you never run out of disk space on your VPS

How to Prune Docker Images Automatically with a Daily Cron job
Prune Docker Containers Automatically


Using Watchtower?

If you're using watchtower, the removal of old Images and Volumes can be achieved with additional arguments on the container -> Click here for more details

Set up a Cron job to automatically Prune all unused docker images, volumes and networks on a daily basis to save you time ensuring you never run out of disk space on your VPS.

I currently use HostCram as my VPS provider.

Before you begin

Having deployed Watchtower in the previous episodes of this series, Docker will now automatically pull and update all of your containers that exist within your docker and docker-compose ecosystem when a new container is released by the author. Unfortunately, a downside of this is that your VPS-attached storage can fill up quickly with old container images if you have a lot of containers that update fairly frequently.

Docker Prune Images

Docker has a fantastic 'prune' command to tell it to clean up all unused docker containers but unfortunately, this is not something that it does by itself so you need to log in now and then and tell it to.

Let's check out the docker prune command:

docker system prune 

command to force docker to prune all dangling containers

Just a word of warning here: this command will delete dangling and unused images (Unused images are images no longer referenced by any containers), networks that are not used, the build cache and any stopped containers you might have.
Terminal output showing the docker system prune command being run
Terminal showing the running docker system prune

If this is the first time you've run this command, you may have a few gigs of data that gets reclaimed, for me this was 0 bytes as I had previously run the command.

Just a note here - if you also want to prune unused volumes {Dangerous} you can simply append --volume onto the same command so the command would read:

docker system prune --volumes

I'm all for saving ourselves time, so let's automate this command 👍.

Daily Cleanup

The simplest way to do this is to run a cronjob daily to execute our prune command.

docker system prune -af  --filter "until=$((30*24))h"

command to force docker to prune all unused containers

Let's break this down a little bit to understand what's happening here:

  • Docker system prune - We're asking Docker to prune unused containers.
  • -af - We've conjoined two flags here. Appending the -a flag forces docker to look for not just dangling containers but all containers that are not in use anymore. The -f flag just prevents the confirmation prompt which typically prompts the user to confirm if they are happing to confirm with the pruning.
Just a word of warning here: 'unused' means "images not referenced by any container": be careful before using -a!
  • --filter - Adding a filter allows us to specify the age of images that we wish to delete. In this case, it's any images that are older than 30 days or 1 month. We're using some basic math in bash here as bash only supports h (Hours). So let's calculate 30*24 hours which gives us 1 month in hours which typically limits the number of containers to a few gigs. You can shorten this time should you have very limited disk space on your VPS.

let's create a new file in the Cron file to house our command:

cd /etc/cron.daily
sudo nano docker-prune

Command to create a new file within the /etc/cron.daily/ folder

Once the file opens add the prune command we created and inform the OS it's a bash file

docker system prune -af  --filter "until=$((30*24))h"

contents of the docker-prune file that we just created

Once you've added the command, hit Ctrl + O and then Ctrl + X to save and close the file

Now that we've created the file we need to tell the operating system that it needs to be executable with the following command:

sudo chmod +x /etc/cron.daily/docker-prune

command to make the file we just created executable

And that's it. Docker will now execute this command daily.

If you want to test it out to see if it will execute correctly next time the cronjob runs, you can force the daily Cron register to run with the following command:

run-parts /etc/cron.daily

Command to execute the daily cron register 

Terminal output showing all the deleted images off the VPS using the Cron.daily command
Image showing the docker prune command was executed successfully