Как запускать сборки в контейнерах Docker от Jenkins

18

Я пытаюсь использовать Jenkins для создания проекта C ++ в контейнере Docker. У меня нет проблем со сборкой в ​​Дженкинсе или сборкой в ​​контейнере за пределами Дженкинса.

Ниже я попробовал. Я опускаю отображение томов для ясности.

Дело 1

Следующая команда успешно запускает сборку в оболочке.

docker run --rm --interactive=true --tty=true $IMAGE make

Однако при запуске в Jenkins в качестве шага «выполнить оболочку» Docker возвращает следующую ошибку.

cannot enable tty mode on non tty input

Дело 2

Следующая команда похожа на предыдущую, но отключает интерактивность.

docker run --rm $IMAGE make

Дженкинс может успешно запустить сборку. Однако при прерывании сборки возникают серьезные проблемы. Сборка сразу помечается как прерванная, но контейнер продолжает работать до завершения сборки. Также контейнер не удаляется после выхода.

При запуске в оболочке команда строится успешно, но ее невозможно прервать. Также контейнер удаляется после выхода.

Вопрос

Кто-нибудь знает, как правильно запускать сборки в контейнерах Docker из Jenkins и сохранять ли возможность отмены сборок?

Использование любого из плагинов Jenkins не вариант, потому что вызовы Docker находятся внутри скриптов и не могут быть легко извлечены.

marcv81
источник
1
Может быть с заданием после сборки, задачей которого является удаление контейнера? А для случаев, когда вы прерываете сборку, может быть, у вас может быть специальная сборка, которая останавливает и удаляет все поддельные контейнеры? Это неоптимально, но, по крайней мере, это легко обойти. :-)
lgeorget
1
Это не совсем соответствует моему определению чистоты :) Но я ценю это предложение, и это, безусловно, верный обходной путь.
marcv81

Ответы:

3

Самый простой способ запустить сборку докеров в Jenkins - это использовать конвейерное задание. Он имеет много встроенных плагинов, которые могут контролировать вашу среду Docker и контейнеры.

несколько примеров

    docker.image("image-name").run() -Runs the container from the image 
    docker.image("image-name").inside(){//your commands} -Runs your commands inside the docker container and also removes your container as soon as your commands are executed.

Для получения дополнительной информации: https://www.cloudbees.com/blog/orchestrating-workflows-jenkins-and-docker

velsim
источник
2

Вы можете реализовать следующий рабочий процесс:

  1. создайте Docker-контейнер и укажите имя, чтобы вы могли легко ссылаться на него (например, в скриптах)
  2. запустите его и используйте что-то в качестве точки входа, которая поддерживает работу контейнера
  3. Используйте docker exec container cmd ...для выдачи команд сборки и тестирования
  4. Остановить контейнер
  5. Удалить изображение

Это docker exec ...похоже на удаленный доступ к сетевой машине. По умолчанию он не интерактивен и не выделяет tty. Это должно подойти для компиляции и выполнения тестовых наборов. Команда правильно перенаправляет статус выхода команды, выполненной внутри контейнера.

Задание на сборку может быть прервано с помощью:

  • docker stop container (отправляет TERM и KILL и ждет между ними), или
  • docker kill container, или даже
  • docker exec container pkill someexecutable

Рабочий процесс с конкретными командами:

$ docker create --name cxx-devel \
    -v $HOME/src:/srv/src:ro -v $HOME/build:/srv/build \
    gsauthof/fedora-cxx-devel:23
$ docker start cxx-devel     # <- entrypoint is /usr/bin/sleep infinity
$ docker exec cxx-devel /srv/src/projecta/build.sh
$ docker exec cxx-devel /srv/src/projecta/check.sh
$ docker stop cxx-devel
$ docker rm cxx-devel

Для реального примера, использующего этот рабочий процесс, вы можете посмотреть этот файл .travis.yml , реальные сценарии CI , сценарий, выполняемый внутри контейнера, и файлы Docker используемых изображений.

maxschlepzig
источник