Quick Tip: List docker images sorted by size

The docker image ls command has an option for filtering output but what if we want to sort the images to find the really hefty ones? You know, the ones that might need to go the way of Old Yeller.

Huh? What’s that, docker? You can’t do that.
If you want something done right…

It ain’t pretty but it works.

docker image ls --format "{{.Repository}}:{{.Tag}} {{.Size}}" | \
awk '{if ($2~/GB/) print substr($2, 1, length($2)-2) * 1000 "MB - " $1 ; else print $2 " - " $1 }' | \
sed '/^0/d' | \
sort -n

Side Note
This assumes that you don’t have images > 999GB.
If you do – I pity you.

Old and busted (docker image ls sample output):

python                                                                    alpine3.10          992aef1d798f        4 months ago        98.7MB
tomcat-fun                                                                alpine              2b7c7bec86f6        5 months ago        140MB
tomcat-fun                                                                latest              04af324bcf10        6 months ago        463MB
python                                                                    latest              7c5fd2af3815        11 months ago       927MB
python                                                                    alpine3.7           a94f1b57a462        11 months ago       81.1MB
tomcatweather                                                             latest              2353bdd18c19        13 months ago       315MB
tomcat                                                                    latest              ca9e2fccef98        13 months ago       463MB
tomcat                                                                    9-jre11-slim        8528526b1274        14 months ago       305MB
python                                                                    v1                  76031d3d6d90        14 months ago       74.2MB
python                                                                    3.6-alpine          a78e257617d1        14 months ago       74.2MB
busybox                                                                   latest              59788edf1f3e        14 months ago       1.15MB

New hotness (sort script sample output):

1MB - busybox:latest
74MB - python:3.6-alpine
74MB - python:v1
81MB - python:alpine3.7
98MB - python:alpine3.10
140MB - tomcat-fun:alpine
305MB - tomcat:9-jre11-slim
315MB - tomcatweather:latest
463MB - tomcat-fun:latest
463MB - tomcat:latest
927MB - python:latest

Explanation

This monster of Frankenstein needs a proper break down:

1. List docker images with filter

List all images but format the output to just show imageName:tag size.

docker image ls --format "{{.Repository}}:{{.Tag}} {{.Size}}"

2. Convert all image sizes to MB

Check if the size (second argument - $2) is listed in gigabytes ($2~/GB/ checks if GB is in $2) and convert it to megabytes by stripping the size unit (substr($2, 1, length($2)-2)) and multiplying it by 1000. Then append MB and the image name ($1).

awk '{
    if ($2~/GB/) 
        print substr($2, 1, length($2)-2) * 1000 "MB - " $1 ; 

If it’s not in gigabytes, assume it’s in megabytes and print out the size and image name.

    else 
        print $2 " - " $1
}'

3. Delete any lines with sizes of 0 (optional)

I had some images that must have broken during creation so they’re listed as 0. Feel free to omit this command. Look for any line starting with 0 and delete it.

sed '/^0/d'

4. Sort from smallest to largest

The -n flag is the important piece as it sorts it numerically rather than lexicographically/alphabetically. If you prefer, you can also pass the -r flag to reverse sort (largest to smallest).

sort -n
# Lexicographically sorted
109MB - nginx:<none>
109MB - nginx:latest
11.4MB - gcr.io/cloud-builders/metadata:latest
113MB - simple-weather:1
117MB - ubuntu:16.04
1260MB - haskell:8.6
132MB - httpd:2.4

# Numerically sorted
11.4MB - gcr.io/cloud-builders/metadata:latest
109MB - nginx:<none>
109MB - nginx:latest
113MB - simple-weather:1
117MB - ubuntu:16.04
132MB - httpd:2.4
1260MB - haskell:8.6

Quick tip; long explanation.