Найти тему
Nuances of programming

Перенос сценариев CI в docker build

Источник: Nuances of Programming

Распространенный сценарий: команда разработчиков поддерживает множество Jenkinsfile, каждый из которых соответствует требованиям проекта. Однако эти сценарии непрерывной интеграции (CI) непригодны для повторного использования в другом хранилище. Причина заключается в том, что каждый проект обладает собственным технологическим стеком, версией, зависимостями для инструментов и т. д.

В таком случае многоэтапные сборки в docker— идеальное решение.

Эта технология уже давно известна, однако многие пользователи не осознают мощности ее потенциала.

Идея заключается в объединении нескольких Dockerfiles в один Dockerfile. Каждый файл будет выполнять определенную задачу в процессе разработки.

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

Начнем с тестирования sonar:

-2
-3

Наконец переходим к последней стадии, которая будет отражена в результирующем образе. На этой стадии используется базовый образ и присутствуют лишь необходимые артефакты:

-4

Jenkinsfile значительно упрощается (пример для Jenkins на Kubernetes):

-5

Этот способ можно использовать практически для каждого проекта!

Основные преимущества:

  • Возможность повторного использования из одной системы CI в другую (например, переход с Jenkins на действия GitHub). Идеально подходит для open source проектов.
  • Тестирование можно выполнить локально с помощью команды docker build.
  • Все, что относится к созданию и тестированию исходного кода, находится в Dockerfile. Следовательно, сценарии CI хранятся отдельно от исходного кода.
  • Меньше возможностей для совершения ошибок: каждый шаг осуществляется в непривилегированном контейнере docker. Избежать docker daemon можно с помощью таких инструментов, как Kaniko.

Таким образом, все детали проекта изолированы, а сценарии CI можно использовать повторно в разных хранилищах, что упрощает инфраструктуру и повышает поддерживаемость.

Примечания

Пропуск шагов

К примеру, я использовал стадию переноса сгенерированной документации в области памяти (bucket) на S3. Этот шаг необходим в том случае, если сборка выполняется в системе CI, в которой предоставлены учетные данные для записи в этой области памяти.

Для этого устанавливаем аргумент build с командой ARG. По умолчанию установлено значение false, однако на своем CI-сервере я запустил docker build --build-arg push-docs=true, после которого выполняется команда aws s3 cp.

Экспорт отчета о тестировании и других артефактов

Главное условие при работе в docker build заключается в том, что артефакты хранятся в промежуточных образах docker. Например, результаты тестирования удобно хранить в рабочем пространстве Jenkins для генерирования статистики.

Любой артефакт можно с легкостью извлечь из любой промежуточной стадии с помощью меток.

Я отметил вторую стадию с помощью stage=test. Таким образом, после docker build можно запустить небольшой сценарий для получения файла test-results.xml

docker cp $(docker image ls --filter label=stage=test -q | head -1):/usr/src/app/tests-results.xml .

docker image ls используется для получения ID образа этой стадии, а docker cp для копирования файла.

Лучшее решение — это использование большого количества МЕТОК для фильтрации определенной сборки от других подобных сборок.

И последний совет: используйте BuildKit 😉

Читайте нас в телеграмме и vk

Перевод статьи Ignacio Millán: Shift your CI scripts to docker build