Read Image Layers with docker history
An image just misbehaved in production, and docker history is how you see exactly what commands built it. This guide gives you a repeatable way to inspect how an image was assembled, expose commands that the default table shortens, and select a particular platform when an image has more than one. The examples match Docker Community Edition CLI 29.8.1, installed here as package docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need the Docker CLI, access to a running Docker daemon, and an image available in the local image store. These commands only read image metadata. They do not remove layers, rebuild an image, or change a tag. Reading history may reveal commands, paths or other build details that you did not intend to disclose, so treat the output as potentially sensitive.
1. Check the installed command
Start with the local command and package version. This is an ordinary command and does not need elevated privileges:
$ docker --version
Docker version 29.8.1, build 4a63305
$ dpkg-query -W -f='${Package} ${Version}\n' docker-ce-cli
docker-ce-cli 5:29.8.1-1~ubuntu.24.04~noble
The standalone docker history command is an alias for docker image history. The synopsis is:
$ docker history [OPTIONS] IMAGE
Use an image reference that is present locally, such as IMAGE_NAME:TAG or a local image ID. Do not replace that placeholder with a tag you have not checked.
Checkpoint
List local images and choose one deliberately:
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
IMAGE_NAME TAG IMAGE_ID ... ...
The repository, tag and ID above are placeholders. Your output will contain the images on your host. If Docker reports that it cannot connect to the daemon, fix that access problem first; do not add sudo automatically. On a host where Docker access is deliberately restricted, ask an administrator to grant the appropriate group or service access rather than changing permissions casually.
2. Read the normal layer table
Run the command with your chosen image reference:
$ docker history IMAGE_NAME:TAG
IMAGE CREATED CREATED BY SIZE COMMENT
IMAGE_ID ... /bin/sh -c ... ... ...
The table is ordered from the image's newest layer towards its base. The columns identify the layer, when it was created, the command associated with it, its reported size, and any comment. Exact IDs, dates and commands depend on the image.
The default output is designed for a terminal. Long values in the IMAGE and CREATED BY columns can be shortened, and the human-readable size and age formatting is enabled by default in this installed version. History is not a Dockerfile: imported images or squashed builds may have less useful command information, and a layer's command does not prove which files changed.
3. Show complete values when investigating a layer
Use --no-trunc when the shortened command or ID is the detail you need:
$ docker history --no-trunc IMAGE_NAME:TAG
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:FULL_IMAGE_ID ... /bin/sh -c ... ... ...
This option affects presentation only. It does not recover build steps that were never recorded. If an image contains secrets in a command or comment, showing the full value can put them into your terminal scrollback, a log collector or a ticket. Before redirecting output, decide whether those destinations are appropriate.
Checkpoint
Compare a quiet ID-only view with the full table:
$ docker history --quiet IMAGE_NAME:TAG
IMAGE_ID
IMAGE_ID
IMAGE_ID
--quiet prints only image IDs, one per history entry. It is useful when another script needs identifiers rather than human-readable text. It is not a count of files or containers.
4. Make a stable report with --format
For scripts and small reports, select fields explicitly with a Go template. This example prints the ID, creation time and recorded command separated by tabs:
$ docker history --no-trunc --format '{{.ID}}\t{{.CreatedAt}}\t{{.CreatedBy}}' IMAGE_NAME:TAG
IMAGE_ID 2026-09-23 05:00:00 +0000 UTC /bin/sh -c ...
The available history fields include .ID, .CreatedSince, .CreatedAt, .CreatedBy, .Size and .Comment. The shell quotes keep the template together as one argument. Keep that quoting when adding pipes or redirects:
$ docker history --format '{{.ID}} {{.Size}} {{.Comment}}' IMAGE_NAME:TAG > image-history.txt
The file is created or replaced by the shell. That is the only state-changing part of this example, and it changes a file in your current directory. Choose an output path carefully if an existing report matters. To undo it, remove that specific report after checking it is the file you intended to create:
$ rm -- image-history.txt
Warning
Do not pass untrusted text as a template or image reference without understanding shell quoting. A template is interpreted by Docker's formatting system, while command substitution and redirection are interpreted by your shell.
5. Inspect one platform variant
When a local image has several platform variants, use --platform with an operating system and optional architecture and variant:
$ docker history --platform linux/amd64 IMAGE_NAME:TAG
IMAGE CREATED CREATED BY SIZE COMMENT
IMAGE_ID ... /bin/sh -c ... ... ...
For example, valid shapes include linux/amd64 and linux/arm64/v8. Without this option, Docker uses the daemon's native platform where available, otherwise the first available one. The requested variant must exist in the local image cache; this command does not fetch it.
If the variant is absent, Docker returns an error rather than silently showing another platform. Pulling an image for a platform is a separate operation and can download data, so confirm the registry, tag and disk space before doing that. No elevated privilege is required by docker history itself, although the daemon's access policy still applies.
6. Handle the common traps
- Unknown image: check
docker image lsand use the exact repository and tag. A tag can point at a different image later, so use an image ID or digest when repeatability matters. - Daemon connection failure: verify the Docker service and your account's daemon access. Do not treat
docker historyas a command that can inspect a remote registry without a daemon. - Short or missing commands: try
--no-trunc, but remember that the image may have been imported, squashed or built with metadata that does not describe every file change. - Unexpected platform: specify
--platformand confirm the variant exists locally. Do not infer the platform from the repository name alone. - Unsafe report handling: review output before sharing it. Build commands can contain package URLs, internal paths, usernames or accidentally embedded credentials.
Done means
- You identified a local image with
docker image ls. - You can read its ordinary layer table with
docker history IMAGE_NAME:TAG. - You know when to use
--no-trunc,--quiet,--formatand--platform. - You checked generated reports for sensitive build details before saving or sharing them.