Content-based тегирование и алиасы

Уровень: expert ~40 мин Практика: Vikunja (продолжение) (AGPL-3.0)

Что нужно знать перед уроком

  • M8.02 — Cache-репозитории — продолжение серии продвинутых тем сборки
  • M5.09 — Жизненный цикл пакета — нужно понимание d8 package build --version, к которому привязывается алиасное тегирование

Что нужно знать перед уроком

M8 урок 2 — предыдущая тема, M5 урок 9d8 package build --version. Этот урок объясняет, как связаны content-based теги Werf и семверные версии Application-пакетов.

Теория

Как Werf вычисляет content-based тег

Каждый собранный образ автоматически получает тег, вычисленный на основе содержимого образа (хэш от финального набора слоёв) — а не от произвольного счётчика сборок или временной метки. Это фундаментальное архитектурное решение Werf: одинаковое содержимое образа при любой пересборке (в любой момент времени, на любой машине) всегда даёт один и тот же content-based тег. Это то самое свойство, которое делает возможной корректную работу dependencies/ImageDigest из M8 урока 1 — зависимость от дайджеста автоматически инвалидируется только при реальном изменении содержимого, а не при каждой сборке.

Автоматическое тегирование по content-based хэшу нельзя отключить — это неотъемлемая часть модели Werf, обеспечивающая корректность кэша и зависимостей между образами.

--add-custom-tag — человекочитаемые алиасы поверх content-based тега

1
2
3
werf build --repo example.org/myproject \
  --add-custom-tag "%image%-latest" \
  --add-custom-tag "v1.2.3"

Доступные шаблонные подстановки:

ШаблонЗначение
%image% / %image_slug% / %image_safe_slug%Имя образа из werf.yaml (нужно, если образов несколько)
%image_content_based_tag%Сам content-based тег

Custom-теги — это дополнительные алиасы, ссылающиеся на тот же самый content-based тег, а не отдельные, независимо хранимые образы. Это значит, что при werf cleanup (M8 урок 5) кастомный тег и связанный с ним content-based тег обрабатываются как единое целое — удаление одного означает удаление другого.

Связь с d8 package build --version из M5

Разобранная в M5 уроке 9 команда d8 package build --version v1.2.3 концептуально делает то же самое, что --add-custom-tag "v1.2.3" — она создаёт человекочитаемый семверный алиас поверх реального content-based тега, вычисленного Werf при сборке образов пакета. Семверная версия Application-пакета — это удобный для человека и системы каталогизации ярлык, но физически образ идентифицируется и кэшируется по своему содержимому, а не по этому ярлыку. Именно поэтому повторная сборка с тем же кодом (и той же семверной версией) не создаёт лишний уникальный образ в registry — Werf распознаёт, что содержимое не изменилось, и просто присваивает новый алиас существующему content-based тегу.

Практический пример экспорта с использованием шаблона тега

1
2
3
werf export \
    --repo example.org/mycompany/myproject \
    --tag example.org/mycompany/myproject/myapp:%image_content_based_tag%

Такой подход позволяет получить финальное имя образа с явным content-based тегом для интеграции с внешними системами, ожидающими конкретный, предсказуемый формат имени образа (например, деплой сторонним инструментом, не знакомым с реестром Werf-специфичных тегов).

Частые ошибки и подводные камни

  • Считать, что каждая семверная версия пакета соответствует уникальному, отдельно хранимому образу. На деле несколько семверных версий (алиасов) могут указывать на один и тот же content-based тег, если содержимое образа между версиями фактически не изменилось (например, был изменён только текст в changelog.yaml, не влияющий на сборку образов).
  • Пытаться отключить автоматическое content-based тегирование. Это невозможно и не нужно — это основа корректности кэша и dependency-механизма Werf, разобранного в M8 уроке 1.
  • Не понимать, что custom-теги и их content-based тег обрабатываются werf cleanup как единое целое. Нельзя оставить custom-тег, удалив при этом связанный с ним content-based тег отдельной политикой очистки — они всегда очищаются вместе.

Практика в кластере

Практики в кластере в этом уроке нет — материал относится к стадии сборки и публикации образов.

Практика разработки

🧩 Практика урока: Vikunja (продолжение) · лицензия AGPL-3.0

Соберите образ пакета Vikunja дважды подряд без изменения кода и убедитесь, что content-based тег идентичен при обеих сборках:

1
2
werf build --repo $CI_REGISTRY_IMAGE --add-custom-tag "%image%-dev"
werf build --repo $CI_REGISTRY_IMAGE --add-custom-tag "%image%-dev"

Шпаргалка команд урока

1
2
werf build --add-custom-tag "%image%-latest"
werf export --tag <repo>/myapp:%image_content_based_tag%

Полная сводная таблица — 📋 werf .

Вопросы для самопроверки

Можно ли отключить автоматическое content-based тегирование в Werf?

Отключение сломало бы гарантию корректной инвалидации кэша между зависимыми образами.

Источник: Werf — документация — auto-tagging cannot be disabled

Что представляют собой custom-теги, добавленные через --add-custom-tag?

Custom-тег и content-based тег — единое целое для целей хранения и очистки.

Источник: Werf — документация — custom tags treated as one

Может ли повторная сборка с той же семверной версией НЕ создать новый образ в registry?

Семверная версия — алиас, физическая идентификация образа идёт по содержимому.

Источник: Рекомендуемая литература

Что означает шаблон %image_content_based_tag% в --add-custom-tag или --tag?

Это способ явно включить content-based тег в человекочитаемый шаблон имени.

Источник: Werf — документация — content-based tag

Рекомендуемая литература

Официальная документация

Статьи и блоги

Книги

  • Nigel Poulton. Docker Deep Dive. 2023. ISBN 978-1916585206.

Связанные материалы