Автосборка Docker-образов на коленке: Git -> Jenkins -> Docker Registry

docker: как блинчик испечьСтатья о том, как максимально просто заставить роботов (в нашем случае — Jenkins) собирать Docker-образы на каждый коммит в проект Git-репозитария.

Рассматриваемая схема

Далее описывается реализация следующей схемы:

  1. Разработчик обновляет код проекта
  2. Jenkins обнаруживает это,
  3. Вытаскивает код из git-репы
  4. Собирает Docker-образ
  5. Запихивает его в репозитарий Docker образов (Docker Registry или Docker Hub, в моём случае Nexus Repository)
  6. Сообщает подписчикам о результатах посредством Slack

 

Порядок действий

Разобъём все работы по реализации означенной схемы на три части:

  1. Создание проекта в Git с Dockerfile‘ом в нём
  2. Создание для этого проекта новой Задачи (Job) в Jenkins
  3. Проверяем, что всё сделали верно

Git-репозитарий

В простейшем случае проект может содержать только Dockerfile, если этого достаточно для сборки образа.

bitbucket-dockerfile-repo

Настройки Jenkins

Source Code Management

В простейшем случае оставляем поле Branch пустым, в этом случае каждый новый коммит будет вызывать создание нового Docker-образа.

Build Triggers

В этом разделе настроим периодичность проверки нашего проекта в Git на наличие нового коммита.

Jenkins-Build_Triggers

Build

Добавим и настроим Docker Build and Publish plugin

В качестве метки (Tag) Docker-образа воспользуемся SHA-1 хэшем коммита

Jenkins-Build

Post-build Actions

Воспользуемся Slack Notification Plugin для сигнализации об успешной сборке, либо о его крахе.

Jenkins-Post-build_Action

Проверка

Slack

При корректных настройках каждый удачный билд будет радовать нас сообщением в Slack:

Jenkins-Slack_Notification

Docker-клиент

A если у нас кроме Jenkins правильно настроен Docker-репозиторий, то новый образ может быть извлечён с помощью консольного клиента.

 

∗∗∗

В целом на этом всё, далее следуют некоторые подсказки, показавшиеся мне интересными.

Дополнения

Git-submodules

В проекте с Dockerfile может ничего кроме Dockerfile не быть. Но иногда необходимо при сборке образа поместить в него какие-то дополнительные артефакты, например: скрипты.

Но иногда возникает потребность засунуть в образ целый проект с кучей файлов. И если этот проект располагается на том же GIT-репозитарии, то проще всего это сделать с помощью Git — Submodules.

Механизм сабмодулей позволяет вместо того, чтобы перемещать файлы физически из одного проекта в другой (либо скриптами, либо капипастой), воспользоваться эдаким аналогом символической ссылки, когда в проекте сохраняется метаинформация о директории и о том, что в ней должно лежать с указанием точного адреса ввиде URL другого git-репозитория.

С Git — Submodules всё понятно — они просто работают. Но есть ли поддержка всего этого в Jenkins?

Да!

В разделе Source Code Management → GIT добавьте дополнительное поведение Advanced sub-modules behaviours и поставьте галку как на рисунке.

SCM-GIT_Advanced-sub-modules-behaviours

Готово.

Вычисляемый Docker-image tag

Иногда в настройках Docker Build and Publish плагина в качестве Tag необходимо указать значение, которое невозможно получить простой комбинаций переменных окружения в соответствующем текстовом поле.

Чтобы обойти это ограничение, делаем следующее: В раздел Build добавляем блок с Execute shell, в котором вычисляем значение для нашего TAG и складываем его в файл tmp.properties (да, просто в файл)

jenkins-complex-tag_exec-shell

Далее воспользуемся возможностями Environment Injector Plugin (всё в том же разделе Build). Извлечём новую переменную окружения из только что созданного файла.

jenkins-complex-tag_inject-env-variables

После этого воспользуемся нашим TAG точно так же, как до этого воспользовались GIT_COMMIT.

jenkins-complex-tag_docker-build-and-publish

Готово