Home / Alt manpages / docker-images(1)

  • docker-images(1)
  • User command
  • linux

List, Filter and Inspect Local Docker Images

You will finish with a reliable way to find images in the local Docker image store, distinguish tags from image IDs, and turn the result into concise output for a shell script. The examples use Docker CLI 29.8.1 from docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble, so check your own version if the output or experimental options differ.

Allow about ten minutes. You need the Docker CLI and access to a running Docker daemon. Listing images is normally a read-only operation and does not need elevated privileges. If your account is not allowed to access the daemon socket, fix that access through your normal Docker installation process or use the approved administrative route. Do not casually add users to the docker group: access to the daemon is effectively high privilege.

1. Check the installed command

Start with the command and package version. This confirms which syntax the examples should match:

$ docker --version
Docker version 29.8.1, build ...
$ dpkg-query -W -f='${Package} ${Version}\n' docker-ce-cli
docker-ce-cli 5:29.8.1-1~ubuntu.24.04~noble

The exact build suffix can vary. The manpage describes docker images as an alias for docker image ls, and the command also accepts docker image list. Pick one spelling and use it consistently in scripts. The grouped docker image ls form makes it clearer that this is image inventory, not container status.

Checkpoint: ask the binary for its supported options before copying an example from another Docker installation:

$ docker images --help
Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

2. List the images currently available

Run the default listing:

$ docker image ls
IMAGE                                          ID             DISK USAGE   CONTENT SIZE   EXTRA
alpine:3                                      294b683cb724       13MB         3.94MB
alpine:latest                                 294b683cb724       13MB         3.94MB
hello-world:latest                            5e2309035332     25.9kB         9.49kB

Your table will contain different repositories, tags, ages and sizes. The default view hides intermediate and dangling images. A repeated ID is not necessarily a duplicate: several tags can refer to the same underlying image, as alpine:3 and alpine:latest do above. The displayed size is the image's cumulative local size, so do not add repeated rows together when estimating storage.

To restrict the list to one repository or tag, pass the reference after the options:

$ docker image ls alpine:3
REPOSITORY   TAG   IMAGE ID       CREATED       SIZE
alpine       3     294b683cb724   ...           13MB

If nothing matches, Docker prints an empty table. That means the image is not present under that local reference; it does not pull the image and it does not prove that a similarly named remote image is unavailable.

3. Make missing images and duplicate tags visible

Use --all when you need intermediate layers and dangling images:

$ docker image ls --all
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
<none>       <none>    1a2b3c4d5e6f   ...           13MB
alpine       latest     294b683cb724   ...           13MB

Rows containing <none> are a description of an untagged local object, not shell syntax. Do not remove them merely because they look untidy. They may still be useful for build caches, and removal belongs to a separate cleanup decision.

For scripts or support tickets that need an unambiguous identifier, use --no-trunc:

$ docker image ls --no-trunc alpine:3
REPOSITORY   TAG   IMAGE ID                                                                  CREATED   SIZE
alpine       3     sha256:294b683cb724...                                                     ...       13MB

The long ID is more suitable for records than the shortened display ID. Exact creation times and the full value vary by image, so treat the row above as a shape, not a fixed result.

4. Filter the inventory

Filters use key=value. The installed command supports filters such as dangling, label, before, since and reference. For example, match only local Alpine references:

$ docker image ls --filter 'reference=alpine:*'
REPOSITORY   TAG      IMAGE ID       CREATED       SIZE
alpine       3        294b683cb724   ...           13MB
alpine       latest   294b683cb724   ...           13MB

Quote the filter so the shell does not expand the wildcard before Docker receives it. To find dangling images without changing anything, use:

$ docker image ls --filter 'dangling=true'
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
<none>       <none>    1a2b3c4d5e6f   ...           13MB

An empty result is a useful result. Do not turn an inventory command into a deletion pipeline such as docker rmi $(docker image ls ...) until you have reviewed every ID and checked whether containers depend on it.

5. Show digests when provenance matters

Tags are convenient names and can move. Add --digests when you need the content-addressed digest recorded alongside the tag:

$ docker image ls --digests alpine
REPOSITORY   TAG      DIGEST   IMAGE ID       CREATED       SIZE
alpine       latest   <none>   294b683cb724   ...           13MB

A locally built image may have no registry digest, shown as <none>. That is not an error and it is not the same thing as the image ID. When a registry digest is present, record the full sha256:... value if you need to reproduce a deployment. The listing command does not fetch a missing digest.

6. Produce stable, smaller output

Use --quiet when a later command needs only image IDs:

$ docker image ls --quiet alpine
294b683cb724

This is still output from a command intended for humans, so avoid assuming a particular ordering. For a report, choose the fields explicitly with a Go template:

$ docker image ls --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}'
REPOSITORY   TAG      ID             SIZE
alpine       3        294b683cb724   13MB
alpine       latest   294b683cb724   13MB

Useful fields include .ID, .Repository, .Tag, .Digest, .CreatedAt and .Size. The table prefix adds column headings. Use --format json when one JSON object per image is easier for your consumer than parsing aligned columns:

$ docker image ls --format json | head -1
{"Containers":"N/A","CreatedAt":"...","Digest":"<none>","ID":"294b683cb724","Repository":"alpine","Size":"13MB","Tag":"latest"}

Keep the single quotes around templates in a POSIX shell. They protect the braces and dollar-like template syntax from accidental shell interpretation.

7. Handle the common failures safely

If Docker reports that it cannot connect to the daemon, the listing itself has not changed anything. Check the active context and daemon status using your site's normal runbook before restarting services. A service restart can disrupt running containers and is not required just to learn the command's flags.

If the command succeeds but an expected repository is absent, check the exact spelling, tag and active Docker context. A different context has a different image store. Do not pull an image as a diagnostic unless you have confirmed the registry, tag, platform and storage impact.

docker image ls is read-only. This guide therefore has no undo command. If you later decide to prune images, treat that as a separate, destructive operation: review the candidates, confirm no required container or rollback depends on them, and retain a recoverable source such as the original registry or an exported archive.

Done means

  • You checked the installed Docker CLI and package version.
  • You can list all ordinary local image tags and understand repeated IDs.
  • You know when --all, --no-trunc and --digests change the evidence shown.
  • You can filter by a quoted reference or dangling status without deleting anything.
  • You can produce IDs, a table or JSON-shaped records for the next tool.
  • You have kept image listing separate from pulling, removing and service-disrupting maintenance.