Хранилище образов передаёт версии с тегами и неизменяемой цифровой идентичностью на сервер
DevOps

Docker-образы, теги, digest и registry: как выбирать версию

Разбираем имена Docker-образов, mutable-теги и неизменяемые digest, проверяем источник, платформу и точную версию перед запуском и обновлением.

Содержание

Docker скачивает образы из registry — сервера, где издатели хранят версии своих образов. В адресе registry.example/team/api:1.4 записаны адрес registry, каталог команды, имя образа и тег 1.4. Тег удобен человеку, но издатель может переназначить его на новую сборку. Digest вида sha256:... вычисляется из описания конкретного содержимого и нужен, когда следует воспроизвести тот же релиз.

Как выбирать версию образа

Для эксперимента допустим осмысленный version tag. Для проверяемого релиза сохраняйте полученный digest и запускайте ту же версию во всех средах. Перед обновлением скачайте новый образ, сравните метаданные, протестируйте его и только затем меняйте зафиксированную ссылку.

Что означает каждая часть имени

registry.example.com/team/api:1.4
└──── registry ────┘ └repo┘ └tag┘

Если registry не указан, Docker обычно обращается к Docker Hub. Если пропущен тег, CLI использует latest. Это значение не означает «последняя стабильная версия»: оно лишь следует политике издателя.

Для публичных базовых образов проверяйте карточку repository и отметку издателя. Docker Official Images, Verified Publisher и Docker-Sponsored Open Source имеют разные модели сопровождения. Совпадающее имя в чужом namespace не становится официальным.

Скачайте явный тег и изучите результат

Следующие команды выполняются на машине с Docker. Они скачивают Alpine с указанным тегом, показывают локальную запись и выводят идентификатор, дату сборки и платформу образа:

sudo docker pull alpine:3.22
sudo docker image ls alpine
sudo docker image inspect alpine:3.22 \
  --format 'id={{.Id}} created={{.Created}} architecture={{.Architecture}} os={{.Os}}'

Дата создания не равна дате установки и не доказывает отсутствие уязвимостей. Она помогает заметить неожиданно старый build, но решение принимают по документации, поддержке и проверке состава.

Получите repository digest:

sudo docker image inspect alpine:3.22 \
  --format '{{range .RepoDigests}}{{println .}}{{end}}'

После pull вывод содержит запись вида alpine@sha256:.... Не копируйте digest из этой статьи: он зависит от выбранной версии и manifest.

Почему тег может измениться, а digest — нет

Тег удобен человеку и может двигаться. Manifest — небольшое описание образа: в нём перечислены его слои и настройки. Digest вычисляется для manifest и позволяет запросить конкретную версию:

sudo docker pull alpine@sha256:ACTUAL_DIGEST

Замените ACTUAL_DIGEST значением, полученным из собственного проверенного pull или registry. Команда с буквальным placeholder должна завершиться ошибкой — это безопаснее, чем незаметно скачать другой образ.

Закрепление digest решает воспроизводимость, но создаёт обязанность обновлять его. Старый зафиксированный образ не получает патчи сам. Рабочая схема сочетает:

  • понятный tag для контекста версии;
  • digest для точного релиза;
  • регулярную проверку обновлений;
  • review изменения digest;
  • smoke-тест и возможность вернуть предыдущий образ.

Тегирование не копирует слои

sudo docker tag alpine:3.22 local/alpine-test:reviewed
sudo docker image ls --digests

Новый тег — ещё одна ссылка на локальный образ, а не независимая копия. Удаление одного тега не обязательно удаляет слои, если на них ссылается другой tag или контейнер.

Не используйте тег stable или production без процесса, который однозначно фиксирует, кто и после каких тестов его перемещает. Для расследования должно быть возможно связать контейнер с digest и commit приложения.

Учитывайте платформу

Один tag может указывать на manifest list для нескольких архитектур. Engine выбирает подходящий вариант для хоста. Проверьте свою архитектуру:

uname -m
sudo docker info --format '{{.Architecture}}'
sudo docker manifest inspect alpine:3.22

При сборке на ARM-ноутбуке и запуске на amd64-сервере нельзя считать локальный image ID универсальным доказательством одинакового содержимого. Фиксируйте платформу вместе с ссылкой на образ.

Для явного pull:

sudo docker pull --platform linux/amd64 alpine:3.22

Не подставляйте эту платформу автоматически: она должна совпадать с целью или поддерживаемой multi-platform сборкой.

Вход в registry и секреты

docker login сохраняет учётные данные через настроенный credential store либо в конфигурации клиента. На сервере не передавайте пароль прямо аргументом. Для неинтерактивной автоматизации используйте ограниченный токен и stdin:

printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com \
  --username "$REGISTRY_USER" --password-stdin

Переменные здесь должны поступать из защищённого окружения, а не быть вписаны в shell history. Токен выдавайте только на нужный namespace и действие. После ручной операции выполните docker logout registry.example.com, если постоянная сессия не требуется.

Проверка перед запуском

Перед тем как доверить образу данные или socket:

  1. подтвердите registry и издателя;
  2. прочитайте документацию по tag и обновлениям;
  3. проверьте поддерживаемую архитектуру;
  4. сохраните digest;
  5. изучите заявленные порты, пользователя и entrypoint;
  6. запустите без privileged, socket и чувствительных mounts;
  7. выполните прикладной smoke-тест.

Метаданные доступны локально:

sudo docker image inspect IMAGE_REFERENCE \
  --format 'user={{.Config.User}} entrypoint={{json .Config.Entrypoint}} cmd={{json .Config.Cmd}}'
sudo docker image history --no-trunc IMAGE_REFERENCE

История слоёв не является полным security-аудитом, но помогает заметить неожиданную установку пакетов, большие слои и опасные build-аргументы.

Удалите только созданный тестовый тег

Перед удалением выясните, какие контейнеры используют образ. Эти команды ничего не очищают массово: первая только показывает связанные контейнеры, вторая удаляет созданное в статье локальное имя:

sudo docker ps -a --filter ancestor=alpine:3.22
sudo docker image rm local/alpine-test:reviewed

Не применяйте docker image prune -a как плановую «оптимизацию» без проверки: она может удалить локальные версии, необходимые для быстрого rollback, и следующему запуску понадобится сеть и доступ к registry.

Практику жизненного цикла контейнера выполняйте через run, logs и inspect. Собственный проверяемый образ создаётся по воспроизводимому Dockerfile, а registry-токены хранятся по правилам работы с секретами.

Источники

Рекламное местоВаша компания здесьРазместить рекламу

Самопроверка

Проверьте, что материал усвоен

Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.

01Что произойдёт при docker pull без явного тега?
02Как зафиксировать точное содержимое образа?
03Что проверить перед использованием стороннего образа?

Разбираем коротко

Частые вопросы

Почему тег latest не означает самую новую безопасную версию?

latest — обычное имя тега без обязательной семантики. Издатель решает, на какой manifest оно указывает, поэтому политику версий нужно читать в документации конкретного образа.

Чем digest надёжнее тега?

Digest является content-addressed идентификатором manifest. Тег можно переназначить, а ссылка по digest выбирает конкретное содержимое, пока оно доступно в registry.

Нужно ли навсегда закреплять старый digest?

Нет. Закрепление делает сборку воспроизводимой, но не приносит исправления автоматически. Digest нужно обновлять контролируемо после проверки новой версии и сохранять историю изменения.