Як перевірити метадані 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.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів