5

I'm building images on a small server and spinning them up with docker-compose.

When it's disk gets full I run docker prune -a so all the stopped containers, dangling image are cleaned out.

But I'd like to keep one or two recent images in case I need to roll back quickly.

The docker prune documentation says --filter until=<timestamp>. But the timestamps from the previous images could be days, weeks or months old.

Then suggested method for pruning by date is:

a) find the timestamp by listing the images with this format

docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}'

which produces

REPOSITORY          TAG                 IMAGE ID            CREATED AT                      SIZE
foo                 latest              2f287ac753da        2017-01-04 13:42:23 -0800 PST   3.98 MB
alpine              latest              88e169ea8f46        2016-12-27 10:17:25 -0800 PST   3.98 MB
busybox             latest              e02e811dd08f        2016-10-07 14:03:58 -0700 PDT   1.09 MB

How can I automatically select the second created at timestamp in the list it produces?

...to then pass it as a variable into

b) docker image prune -a --force --filter "until=<2rd timestamp from list>"

Is there an way to use awk ? Is there another way to leave an extra image ?

2 Answers 2

4

The problem is that the date format isn't ideal.

Supported formats for date formatted time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00, and 2006-01-02

Reference: https://docs.docker.com/engine/reference/commandline/system_prune/#filtering

So this is really just a half answer, since it will use the date and the local timestamp.

The local timezone on the daemon will be used if you do not provide either a Z or a +-00:00 timezone offset at the end of the timestamp.

Thankfully, this comes sorted.

~: docker images --format '{{.CreatedAt}}'
2020-06-09 12:44:57 -0700 PDT
2020-05-29 14:19:46 -0700 PDT
2020-05-05 13:40:47 -0700 PDT
2020-04-28 11:55:11 -0700 PDT
2020-03-09 10:35:34 -0700 PDT
2020-03-09 10:14:43 -0700 PDT
2020-03-09 10:14:43 -0700 PDT
2020-03-09 10:14:43 -0700 PDT
2020-02-26 07:10:58 -0800 PST

I don't know how to transform timestamps in bash off the top of my head, so let's just do this the quick and messy way... the whole date!

 ~: docker images --format '{{.CreatedAt}}' | sed -n '2p' | awk '{print $1;}'
2020-05-29

Now we can do command substitution.

~: docker image prune --force --filter "until=`docker images --format '{{.CreatedAt}}' | sed -n '2p' | awk '{print $1;}'`"
Total reclaimed space: 1.344GB

I didn't put a heck of a lot of thought in to this answer, so there may be some edges cases I didn't consider. Also, if someone with better bash-fu can transform that timestamp, that would be awesome.

1
  • Using sed -n '2p' to select (maybe 3p) is exactly what I wanted :)
    – Kickaha
    Commented Jul 29, 2020 at 17:55
1

It is also possible to use before filter.

E.g., if the question would be about removing "all but 1(one) most recent image", the answer could be:

docker images -q --filter before=$nameTag $nameOnly | xargs --no-run-if-empty docker rmi --force || true

And Jenkins method could look like:

def previousImagesCleanup(String nameTag) {
  String nameOnly=nameTag.split(':')[0]
  log.info("Clean up if build succeeded - delete images prior to the current one ($nameTag). Preserving last one for cache purposes.")
  sh("docker images -q --filter before=$nameTag $nameOnly | xargs --no-run-if-empty docker rmi --force || true")
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.