<p>It is also possible to use <code>before</code> filter.</p>
<p>E.g., if the question would be about removing &quot;all but 1(one) most recent image&quot;, the answer could be:</p>
<pre class="lang-sh prettyprint-override"><code>docker images -q --filter before=$nameTag $nameOnly | xargs --no-run-if-empty docker rmi --force || true
</code></pre>
<p>And Jenkins method could look like:</p>
<pre class="lang-java prettyprint-override"><code>def previousImagesCleanup(String nameTag) {
  String nameOnly=nameTag.split(':')[0]
  log.info(&quot;Clean up if build succeeded - delete images prior to the current one ($nameTag). Preserving last one for cache purposes.&quot;)
  sh(&quot;docker images -q --filter before=$nameTag $nameOnly | xargs --no-run-if-empty docker rmi --force || true&quot;)
}
</code></pre>

CC BY-SA 4.0
2023-10-03T14:51:20.693Z
2023-10-03T14:51:20.693Z
Aleksejs Spiridonovs
<p>The problem is that the date format isn't ideal.</p>
<blockquote>
<p>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</p>
</blockquote>
<p>Reference: <a href="https://docs.docker.com/engine/reference/commandline/system_prune/#filtering" rel="nofollow noreferrer">https://docs.docker.com/engine/reference/commandline/system_prune/#filtering</a></p>
<p>So this is really just a <em>half</em> answer, since it will use the date and the local timestamp.</p>
<blockquote>
<p>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.</p>
</blockquote>
<p>Thankfully, this comes sorted.</p>
<pre><code>~: 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
</code></pre>
<p>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!</p>
<pre><code> ~: docker images --format '{{.CreatedAt}}' | sed -n '2p' | awk '{print $1;}'
2020-05-29
</code></pre>
<p>Now we can do command substitution.</p>
<pre><code>~: docker image prune --force --filter &quot;until=`docker images --format '{{.CreatedAt}}' | sed -n '2p' | awk '{print $1;}'`&quot;
Total reclaimed space: 1.344GB
</code></pre>
<p>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.</p>

CC BY-SA 4.0
2020-07-29T17:55:33.090Z
Using sed -n '2p' to select (maybe 3p) is exactly what I wanted :)
Kickaha
CC BY-SA 4.0
2020-07-29T16:41:20.333Z
2020-07-29T16:41:20.333Z
Woodland
<p>I'm building images on a small server and spinning them up with docker-compose.</p>
<p>When it's disk gets full I run <code>docker prune -a</code> so all the stopped containers, dangling image are cleaned out.</p>
<p>But I'd like to keep one or two recent <strong>images</strong> in case I need to roll back quickly.</p>
<p>The <a href="https://docs.docker.com/engine/reference/commandline/image_prune/" rel="nofollow noreferrer">docker prune documentation</a> says <code>--filter until=&lt;timestamp&gt;</code>. But the timestamps from the previous images could be days, weeks or months old.</p>
<p>Then suggested method for pruning by date is:</p>
<p>a) find the timestamp by listing the images with this format</p>
<p><code>docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}'</code></p>
<p><strong>which produces</strong></p>
<pre><code>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
</code></pre>
<p>How can I automatically select the second <code>created at</code> timestamp in the list it produces?</p>
<p>...to then pass it as a variable into</p>
<p>b)
<code>docker image prune -a --force --filter &quot;until=&lt;2rd timestamp from list&gt;&quot;</code></p>
<p>Is there an way to use awk ? Is there another way to leave an extra image ?</p>

<docker><docker-compose>
How to prune all but two most recent docker images?
Kickaha
# How to prune all but two most recent docker images?

(Asked by: username_0 on 2020-07-29)

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=. 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 ?

**Tags:** docker, docker-compose


---

## 2 answers

### Answer by username_2 on 2020-07-29. Score: 4 | Accepted answer

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.

> **Comments:**
> **username_0**: Using sed -n '2p' to select (maybe 3p) is exactly what I wanted :)  

---

### Answer by username_1 on 2023-10-03. Score: 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")
}


---

