Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2023-10-03T14:51:20.693Z
Answers: 2023-10-03T14:51:20.693Z
Answers: Aleksejs Spiridonovs
Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2020-07-29T17:55:33.090Z
Answers: Using sed -n '2p' to select (maybe 3p) is exactly what I wanted :)
Answers: Kickaha
Answers: CC BY-SA 4.0
Answers: 2020-07-29T16:41:20.333Z
Answers: 2020-07-29T16:41:20.333Z
Answers: Woodland
Body: <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>
  
Tags: <docker><docker-compose>
Title: How to prune all but two most recent docker images?
UserDisplayName: Kickaha
ThreadText: # 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](https://docs.docker.com/engine/reference/commandline/image_prune/) 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 ?
  
  **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:
  
  ```sh
  docker images -q --filter before=$nameTag $nameOnly | xargs --no-run-if-empty docker rmi --force || true
  
  ```
  
  And Jenkins method could look like:
  
  ```java
  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")
  }
  
  ```
  
  
  ---
  
  