Процедура публикации образа

Процесс публикации образа при обычной работе с Docker, состоит из следующих этапов:

docker tag REPO:TAG
docker push REPO:TAG
docker rmi REPO:TAG
  1. Получение имени или id собранного локального образа.
  2. Создание временного образа-псевдонима, состоящего из следующих частей:
  3. Публикация образа-псевдонима в Docker registry.
  4. Удаление временного образа-псевдонима.

В werf реализована иная логика публикации образа, описанного в конфигурации:

  1. Создание нового образа с определенным именем на основе соответствующего собранного образа. В созданном образе хранится информация о применяемой схеме тегирования, необходимая для внутреннего использования werf (эта информация сохраняется с использованием docker labels). Далее, такая информация будет упоминаться как мета-информация образа. werf использует мета-информацию образа в процессе деплоя и процессе очистки.
  2. Публикация созданного образа в Docker registry.
  3. Удаление образа, созданного на этапе 1.

Далее, такой процесс будет называться процессом публикации образа.

Результатом процесса публикации образа является образ, именованный согласно правил именования образов и загруженный в Docker registry. Все эти шаги выполняются с помощью команды werf publish или werf build-and-publish.

Именование образов

Во время процесса публикации образа, werf формирует имя образа используя:

  • значение параметра --images-repo;
  • значение параметра --images-repo-mode;
  • имя образа из файла конфигурации werf.yaml;
  • значение параметра тегирования.

Итоговое имя Docker-образа имеет формат — DOCKER_REPOSITORY:TAG.

Параметры --images-repo и --images-repo-mode определяют адрес хранения образов и формат его имени в репозитории. Если в конфигурации проекта (файл werf.yaml) описан только один безымянный образ, то значение параметра --images-repo используется в качестве имени Docker-репозитория без изменений. Имя Docker-образа в таком случае будет соответствовать шаблону: IMAGES_REPO:TAG.

Если в конфигурации проекта (файл werf.yaml) описано несколько образов, то шаблон имени Docker-образа будет зависеть от значения параметра --images-repo-mode:

  • IMAGES_REPO:IMAGE_NAME-TAG в случае значения monorepo для параметра --images-repo-mode;
  • IMAGES_REPO/IMAGE_NAME:TAG в случае значения multirepo для параметра --images-repo-mode (используется по умолчанию).

Большинство реализаций Docker registry позволяют создавать иерархию репозиториев, например, COMPANY/PROJECT/IMAGE. В этом случае вам нет необходимости менять значение парамера --images-repo-mode со значения по умолчанию — multirepo. Но, если у вас в проекте описано несколько образов, и вы работаете с Docker registry неподдерживающим иерархию репозиториев (самый яркий пример, это — Docker Hub), то вам потребуется указать значение monorepo в параметре --images-repo-mode. Подробнее о работе режима monorepo/multirepo можно прочитать в нашей статье.

Значение, указываемое для параметра --images-repo может быть также передано через переменную окружения $WERF_IMAGES_REPO.

Значение, указываемое для параметра --images-repo-mode может быть также передано через переменную окружения $WERF_IMAGES_REPO_MODE.

Именование образов должно быть одинаковым при выполнении команд publish, build-and-publish, deploy, а также команд процесса очистки. В противном случае вы можете получить не работающий pipeline и потерю образов и стадий по результатам работы очистки

Docker-тег определяется исходя из используемых параметров --tag-*:

option description
--tag-git-tag TAG Используется стратегия тегирования git-tag, — тегирование осуществляется по указанному git-тегу
--tag-git-branch BRANCH Используется стратегия тегирования git-branch, — тегирование осуществляется по указанной git-ветке
--tag-git-commit COMMIT Используется стратегия тегирования git-commit, — тегирование осуществляется по указанному хэшу git-коммита
--tag-custom TAG тегирование осуществляется по указанному произвольному тегу

Все передаваемые параметры тегирования валидируются, с учетом стандартных ограничений Docker на содержание имени тега образа. При необходимости, вы можете использовать слагификацию (slug, slugify — преобразование текста к виду, удобному для восприятия человеком) тегов, читай подробнее об этом в соответствующей статье.

Используя параметры --tag-*, вы не просто указываете тег, которым нужно протегировать образ, а также определяете стратегию тегирования. Стратегия тегирования влияет на операцию очистки. В частности, политика очистки выбирается в зависимости от стратегии тегирования, а в случае использования стратегии тегирования по произвольному тегу политика очистки не применяется совсем.

Использование параметров тегирования --tag-git-* подразумевает указание аргументов в виде значений тегов, веток и коммитов git. Все такие параметры разработаны с учетом совместимости с современными CI/CD системами, в которых выполнение задания pipeline CI происходит в отдельном экземпляре git-дерева для конкретного git-коммита, а имена тега, ветки и хэш коммита передаются через переменные окружения (например, для GitLab CI это CI_COMMIT_TAG, CI_COMMIT_REF_NAME и CI_COMMIT_SHA).

Объединение параметров

Любые параметры тегирования могут использоваться одновременно в любом порядке при выполнении команды werf publish или werf build-and-publish. В случае передачи нескольких параметров тегирования, werf создает отдельный образ на каждый переданный параметр тегирования, согласно каждому описанному в конфигурации проекта образу.

Примеры

Два образа для одного git-тега

Имеем файл конфигурации werf.yaml с описанными двумя образами — backend и frontend.

Выполнение команды:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-git-tag v1.2.0

приведет к созданию следующих образов соответственно:

  • registry.hello.com/web/core/system/backend:v1.2.0
  • registry.hello.com/web/core/system/frontend:v1.2.0

Два образа для git-ветки

Имеем файл конфигурации werf.yaml с описанными двумя образами — backend и frontend.

Выполнение команды:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-git-branch my-feature-x

приведет к созданию следующих образов соответственно:

  • registry.hello.com/web/core/system/backend:my-feature-x;
  • registry.hello.com/web/core/system/frontend:my-feature-x.

Два образа для git-ветки, в названии которой есть специальные символы

Имеем файл конфигурации werf.yaml с описанными двумя образами — backend и frontend.

Выполнение команды:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-git-branch $(werf slugify --format docker-tag "Features/MyFeature#169")

приведет к созданию следующих образов соответственно:

  • registry.hello.com/web/core/system/backend:features-myfeature169-3167bc8c;
  • registry.hello.com/web/core/system/frontend:features-myfeature169-3167bc8c.

Обратите внимание, что команда werf slugify генерирует значение, допустимое для использования в качестве Docker-тега. Читайте подробнее про команду slug в соответствующем разделе.

Два образа в задании GitLab CI

Имеем файл конфигурации werf.yaml с описанными двумя образами — backend и frontend. Имеем проект web/core/system в GitLab, и сконфигурированный Docker registry для проекта — registry.hello.com/web/core/system.

Запуск следующей команды в задании pipeline GitLab CI для ветки core/feature/ADD_SETTINGS:

type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
werf publish --stages-storage :local

приведет к созданию следующих образов соответственно:

  • registry.hello.com/web/core/system/backend:core-feature-add-settings-df80fdc3;
  • registry.hello.com/web/core/system/frontend:core-feature-add-settings-df80fdc3.

Обратите внимание, что werf автоматически применяет слагификацию к Docker-тегу core/feature/ADD_SETTINGS, — он будет конвертирован в тег core-feature-add-settings-df80fdc3. Эта конвертация выполняется при вызове команды werf ci-env, которая определяет название ветки из переменных окружения задания GitLab CI, слагифицирует его и заносит результат в переменную окружения WERF_TAG_GIT_BRANCH (альтернативный путь установки значения параметра --tag-git-branch). Читайте подробнее про команду slug в соответствующем разделе.

Безымянный образ в задании GitLab CI

Имеем файл конфигурации werf.yaml с описанным безымянным образом. Имеем проект web/core/queue в GitLab, и сконфигурированный Docker registry для проекта — registry.hello.com/web/core/queue.

Запуск следующей команды в задании pipeline GitLab CI для тега v2.3.:

type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
werf publish --stages-storage :local

приведет к созданию образа registry.hello.com/web/core/queue:v2.3.1.