Як перевірити метадані Docker image?
Inspect Docker image-метаданих це те, що ти робиш перед pull, після pull, при дебагу «чому image виріс?» або коли хочеш точно знати, що image обіцяє робити у runtime. Три CLI-tools покривають територію.
Теорія
TL;DR
docker inspect= повний JSON-dump config image, шарів, labels, архітектури, розміру.docker history= хронологічний список шарів з інструкцією, що створила кожен.docker manifest inspect= registry-level manifest (multi-arch info, layer-digests).dive(third-party) = інтерактивний TUI, що показує layer-by-layer file-зміни.- Усі працюють локально; деякі проти remote-image через registry.
docker inspect
Головна команда. Повертає 100+ рядковий JSON. Бери --format, щоб витягати конкретні поля:
# Усе (багато)
docker inspect nginx:1.27
# Конкретні поля
docker inspect nginx:1.27 --format '{{.Id}}'
docker inspect nginx:1.27 --format '{{.Architecture}}'
docker inspect nginx:1.27 --format '{{.Size}}'
docker inspect nginx:1.27 --format '{{.Config.Cmd}}'
docker inspect nginx:1.27 --format '{{.Config.Entrypoint}}'
docker inspect nginx:1.27 --format '{{.Config.User}}'
docker inspect nginx:1.27 --format '{{.Config.WorkingDir}}'
# JSON секції
docker inspect nginx:1.27 --format '{{json .Config.Env}}' | jq
docker inspect nginx:1.27 --format '{{json .Config.ExposedPorts}}' | jq
docker inspect nginx:1.27 --format '{{json .Config.Labels}}' | jqЗручні поля:
.Id— content-digest image.RepoTags— tag, що вказують на цей image.RepoDigests— digest-посилання у registry.Architecture,.Os— цільова платформа (amd64/linux).Size— загальний розмір (у байтах).Created— коли image зібрано.Config.*— runtime-config (Cmd, Entrypoint, Env, Labels, ExposedPorts, User, WorkingDir, Volumes, Healthcheck).RootFS.Layers— список digest шарів (у порядку).History— build-історія (Dockerfile-еквівалентні кроки)
docker history
Показує шари з найстарішого (низ) до найновішого (верх) з інструкцією, що створила кожен:
$ docker history nginx:1.27-alpine
IMAGE CREATED CREATED BY SIZE COMMENT
4f06b3e2c0c1 2 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemo… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
<missing> 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 2 weeks ago /bin/sh -c set -x && addgroup -g 101 -S… 8.94MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.27.4 0B
<missing> 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:abcd1234… 7.79MBБери --no-trunc для повних інструкцій:
docker history --no-trunc nginx:1.27-alpine<missing> означає, що проміжний image не має окремого ID локально, лише фінальний. Інструкції все одно зберігаються у метаданих.
docker manifest inspect
Показує registry-side manifest, включно з multi-arch info:
$ docker manifest inspect nginx:1.27
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"digest": "sha256:abc123...",
"platform": { "architecture": "amd64", "os": "linux" }
},
{
"digest": "sha256:def456...",
"platform": { "architecture": "arm64", "os": "linux" }
},
...
]
}Корисно для підтвердження, що image підтримує твою архітектуру перед pull, або для пошуку digest конкретної платформи.
dive (third-party)
Не вбудовано у Docker, але стандартний tool для розуміння вмісту шарів:
$ dive nginx:1.27-alpineВідкриває інтерактивний TUI:
- Верхня панель: шари з розміром і командою.
- Нижня панель: file-tree обраного шару (з diff від попереднього).
- Права панель: image-деталі (efficiency-score, wasted space).
Неоціненно для «чому image 2 GB?», бачиш точні файли, що дав кожен шар.
Корисні патерни
«Який CMD запуститься?»
docker inspect <img> --format '{{.Config.Entrypoint}} {{.Config.Cmd}}'«Які env-змінні запечено?»
docker inspect <img> --format '{{json .Config.Env}}' | jq«На яких портах image слухає?»
docker inspect <img> --format '{{json .Config.ExposedPorts}}' | jq«Як який користувач container крутиться?»
docker inspect <img> --format '{{.Config.User}}'
# порожньо = root (обережно)«Знайти найбільший шар»
docker history --format '{{.Size}}\t{{.CreatedBy}}' --no-trunc <img> | sort -h«Який content-digest?»
docker inspect <img> --format '{{index .RepoDigests 0}}'
# myimg@sha256:abc123...Незмінний ідентифікатор, бери це у прод-manifest замість мінливих tag.
Типові помилки
Плутати docker inspect для image vs container
docker inspect myimg # працює на image
docker inspect mycontainer # працює на container
# Та сама команда, різні об'єкти → різні поля доступніSchema відрізняється. Container inspect включає .State (running/exited), .NetworkSettings, .Mounts. Image inspect ні.
Читати <missing> як помилку
<missing> у docker history означає, що проміжний layer-ID не зберігається локально. Image все одно працює; це просто артефакт того, як Docker squashes-проміжні метадані. Не проблема.
Забути, що history показує DOCKERFILE-КРОКИ, не вміст файлів
/bin/sh -c apt-get update && apt-get install ... && rm -rf /var/lib/apt/lists/*
Це каже, що build робив, не що файли потрапили куди. Для файлів бери dive або docker save + tar-inspect.
Inspect image, що не pull'нув
Локальний docker inspect потребує image у локальному кеші. Для remote-image: спочатку docker pull або бери docker manifest inspect (працює проти registry).
Реальне застосування
- Pre-deploy верифікація:
docker inspect, щоб підтвердити, що CMD, USER, EXPOSE відповідають очікуванням перед promote. - Compliance-аудит: scan усіх прод-image на OCI-labels, expected user, no root.
- Image-size розслідування:
diveіdocker history, щоб знайти найбільші шари. - Multi-arch верифікація:
docker manifest inspect, щоб переконатися, що твій image має варіанти amd64 і arm64 перед деплоєм у змішаних кластерах. - Відтворення білдів:
docker historyпоказує build-команди; cross-reference з source Dockerfile.
Питання для поглиблення
Q: Яка різниця між Id і RepoDigest?
A: Id це локальний image-ID, hash config-blob. RepoDigest це registry-side digest (hash manifest, використовується у pull-by-digest). Відрізняються, бо manifest-hash включає tag/registry-info, а локальний ID лише content.
Q: Як побачити, що у конкретному шарі?
A: dive найпростіше. Руками: docker save <img> -o img.tar && tar xf img.tar дає директорію на шар з вмістом.
Q: Чи можу inspect image running-container?
A: docker inspect <container> --format '{{.Image}}' повертає image-ID; передай його у docker inspect для image-метаданих.
Q: Яка різниця між docker inspect і docker image inspect?
A: docker inspect загальний (працює на image, container, volume, мережах). docker image inspect явна форма лише для image. Той самий output для image.
Q: (Senior) Як написати CI-перевірку, що падає, якщо image має погані метадані?
A: Малий скрипт, що крутить docker inspect і docker history, парсить через jq і assert: (1) Config.User не порожній (без root-container), (2) обов'язкові OCI-labels present (org.opencontainers.image.source, version), (3) без latest-tag у Config.Image, (4) загальний Size під порогом, (5) layer-count нижче max. Прив'яжи це у CI як gate; завали pipeline, якщо assertion ламається. Сильніша версія використовує dive --ci, що перевіряє image-efficiency-score автоматично.
Приклади
Швидкий image-аудит
$ IMG=nginx:1.27-alpine
$ docker inspect $IMG --format \
'Id={{.Id}} Arch={{.Architecture}} OS={{.Os}} Size={{.Size}} User={{.Config.User}} Cmd={{.Config.Cmd}}'
Id=sha256:4f06b3e2c0c1... Arch=amd64 OS=linux Size=54923456 User= Cmd=[nginx -g daemon off;]
$ docker history --format 'table {{.Size}}\t{{.CreatedBy}}' --no-trunc $IMG | head
SIZE CREATED BY
0B /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon off;"]
0B /bin/sh -c #(nop) STOPSIGNAL SIGQUIT
0B /bin/sh -c #(nop) EXPOSE 80
8.94MB /bin/sh -c set -x && addgroup -g 101 -S nginx ...
0B /bin/sh -c #(nop) ENV NGINX_VERSION=1.27.4
0B /bin/sh -c #(nop) CMD ["/bin/sh"]
7.79MB /bin/sh -c #(nop) ADD file:abcd...Чотири факти на одному погляді плюс layer-breakdown.
Manifest-inspect для multi-arch
$ docker manifest inspect nginx:1.27 | \
jq '.manifests[] | {arch: .platform.architecture, digest: .digest}'
{ "arch": "amd64", "digest": "sha256:abc..." }
{ "arch": "arm64", "digest": "sha256:def..." }
{ "arch": "arm/v7", "digest": "sha256:ghi..." }
{ "arch": "386", "digest": "sha256:jkl..." }Підтверджує, які платформи image підтримує і дає per-platform digests для пінінгу.
Знайти найбільший шар
$ docker history --format '{{.Size}}|{{.CreatedBy}}' --no-trunc node:22-alpine \
| grep -v '^0B|' \
| sort -h \
| tail -5
47.2MB|/bin/sh -c apk add --no-cache python3 ...
42.5MB|/bin/sh -c addgroup -g 1000 node ...
105MB|/bin/sh -c set -ex; ... npm installНайбільший контрибутор (тут npm install) це твоя перша мета, якщо треба зменшити image.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.