Автоматическая сборка цепочек в том же хранилище Docker Hub

Из-за ограничений по времени сборки Docker Hub я решил разделить Dockerfile трудоемкой автоматической сборки в 3 файла. Каждая из этих "сборок" заканчивается в пределах временных ограничений Docker Hub.

Теперь у меня есть следующие настройки в том же хранилище:

| branch | dockerfile         | tag    |
| ------ | ------------------ | ------ |
| master | /step-1.Dockerfile | step-1 |
| master | /step-2.Dockerfile | step-2 |
| master | /step-3.Dockerfile | step-3 |

Изображения строятся друг на друге в следующем порядке:

  • step-1.Dockerfile: FROM ubuntu
  • step-2.Dockerfile: FROM me/complex-image:step-1
  • step-3.Dockerfile: FROM me/complex-image:step-2

Отдельное веб-приложение запускает создание step-1 используя URL-адрес "триггера сборки", предоставленный Docker Hub. (к которому {"docker_tag": "step-1"}' полезная нагрузка добавлена) Однако Docker Hub не позволяет автоматически запускать step-2 затем step-3 послесловие.

Q: Как я могу автоматически запустить следующие шаги сборки в соответствующем порядке? (т.е. триггер step-2 после step-1 отделки. Затем, триггер step-3 после step-2 отделки)

NB: я не хочу устанавливать отдельные репозитории для каждого из step-i затем свяжите их, используя "Ссылки на репозиторий" Docker Hub. Я просто хочу связать теги в том же репо.

Примечание. До сих пор моим решением было присоединить Docker Hub Webhook к веб-приложению, которое я создал. когда step-n заканчивается (т.е. вызывает URL моего веб-приложения с помощью JSON, содержащего имя тега step-n) веб-приложение использует "триггер сборки" для запуска step-n+1, Это работает, как и ожидалось, однако, мне интересно, есть ли "лучший" способ делать вещи.

РЕДАКТИРОВАТЬ: По просьбе Кена Кокрейна Вот начальные Dockerfile а также "сценарий сборки", который он использует. Я просто пытался докеризовать Клинга. (интерпретатор C++). Нужно скомпилировать llvm, clang и cling. Как и следовало ожидать, в зависимости от машины, для этого требуется несколько часов, а Docker Hub позволяет "только" собирать максимум 2 часа:) Образы "sub build", которые я добавил позже (все еще в develop филиал) построить часть всего этого каждый. Я не уверен, что здесь есть какая-то дальнейшая оптимизация.

Кроме того, чтобы протестировать различные идеи (и избежать ожидания в течение нескольких часов), я настроил еще один репо с аналогичной структурой. (единственное отличие состоит в том, что его Dockerfile не делай так много работы)

ОБНОВЛЕНИЕ 1: вариант 5: как и ожидалось, curl от step-1.Dockerfile был проигнорирован:

Settings > Build Triggers > Last 10 Trigger Logs

| Date/Time                 | IP Address      | Status  | Status Description       | Request Body               | Build Request |
| ------------------------- | --------------- | ------- | ------------------------ | -------------------------- | ------------- |
| April 30th, 2016, 1:18 am | <my.ip.v4.addr> | ignored | Ignored, build throttle. | {u'docker_tag': u'step-2'} | null          |

Другая проблема с этим подходом состоит в том, что он требует, чтобы я поместил (секретный) токен триггера сборки в Dockerfile на всеобщее обозрение:) (надеюсь, у Docker Hub есть возможность сделать его недействительным и сгенерировать еще один)

ОБНОВЛЕНИЕ 2: Вот моя текущая попытка: это в основном приложение Heroku, которое имеет периодический "триггер" APScheduler, который запускает начальный шаг сборки, и обработчик веб-крюка Flask, который "распространяет" сборку. (т.е. он имеет упорядоченный список тегов сборки. Каждый раз, когда он вызывается webhook, он запускает следующий шаг сборки) Я продолжу работать над этим в свободное время. (предложения приветствуются:))

3 ответа

Недавно было такое же требование для цепочки зависимых сборок, и он выполнил это, используя автоматизированные сборки Docker Cloud:

  • Создайте репозиторий с правилами сборки для каждого Dockerfile это должно быть построено.
  • Отключить Autobuild опция для всех правил сборки в зависимых репозиториях.
  • Добавьте сценарий оболочки с именем hooks\post_push в каждом каталоге, содержащем Dockerfile у которого есть иждивенцы со следующим кодом:

    for url in $(echo $BUILD_TRIGGERS | sed "s/,/ /g"); do
      curl -X POST -H "Content-Type: application/json" --data "{ \"build\": true, \"source_name\": \"$SOURCE_BRANCH\" }" $url
    done
    
  • Для каждого хранилища с иждивенцами добавьте Build Environment Variable названный BUILD_TRIGGERS для автоматической сборки, и установите Value в разделенный запятыми список URL-адресов триггеров сборки для каждой зависимой автоматической сборки.

Используя эту настройку, отправка в корневой репозиторий инициирует сборку корневого образа, как только он завершится и будет выдвинут post_push крюк будет выполнен. В хуке POST создается для каждого зависимого триггера сборки репозитория, содержащего имя ветки или тег, который строится в теле запроса. Это приведет к запуску соответствующего правила сборки зависимого репозитория.

Сколько времени занимает сборка? Вы можете опубликовать свой Dockerfile?

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

Вариант 2: это то, что вы уже делаете, используя стороннее приложение для запуска сборок в указанном порядке.

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

Вариант 4: разбить его на несколько репо, тогда вы можете использовать ссылки репо.

Вариант 5: Тотальный взлом, в крайнем случае (не уверен, сработает ли он). Вы добавляете оператор CURL в последнюю строку вашего Dockerfile, чтобы опубликовать ссылку триггера сборки репо с указанным тегом для следующего шага. Вам может понадобиться добавить спящий режим на следующем шаге, чтобы дождаться окончания передачи в концентратор, если вам нужен один тег для следующего.

Честно говоря, лучшим из них является вариант 1: все, что вы делаете, должно быть в состоянии завершить в отведенное время, вы, вероятно, делаете некоторые вещи, которые мы можем оптимизировать, чтобы сделать все это быстрее. Если вы получите его в срок, то все остальное не нужно.

Это можно сделать, изменив настройки сборки в хранилищах Docker Hub.

Сначала создайте Automated Build для /step-1.Dockerfile вашего репозитория GitHub, с тегом step-1, Этот не требует никаких специальных настроек.

Затем создайте еще один Automated Build для /step-2.Dockerfile вашего репозитория GitHub, с тегом step-2, В настройках сборки снимите флажок " Когда активен", сборки будут происходить автоматически при толчках. Также добавьте ссылку на репозиторий me/step-1,

Сделать то же самое для step-3 (связывая это с me/step-2).

Теперь, когда вы отправляете в репозиторий GitHub, он запускает шаг 1 для сборки; когда это закончится, шаг-2 будет построен, а после этого шаг-3 будет построен.

Обратите внимание, что вам нужно подождать, пока предыдущий этап не будет успешно собран, прежде чем вы сможете добавить ссылку на репозиторий.

Я просто попробовал другой ответ, и они у меня не работают, поэтому я изобрел другой способ объединения сборок, используя отдельную ветку для каждого правила сборки, например:

master              # This is for docker image tagged base
docker-build-stage1 # tag stage1
docker-build-latest # tag latest
docker-build-dev    # tag dev

где stage1 зависит от base, latest зависит от stage1, dev основан на latest.

В каждой из зависимостей post_push крючок, я назвал приведенный ниже сценарий с прямыми зависимостями от самого себя:

#!/bin/bash -x

git clone https://github.com/NobodyXu/llvm-toolchain.git
cd llvm-toolchain
git checkout ${1}
git merge --ff-only master

# Set up push.default for push
git config --local push.default simple

# Set up username and passwd
# About the credential, see my other answer:
#     https://stackru.com/a/57532225/8375400
git config --local credential.helper store
echo "https://${GITHUB_ROBOT_USER}:${GITHUB_ROBOT_ACCESS_TOKEN}@github.com" > ~/.git-credentials

exec git push origin HEAD

Переменные GITHUB_ROBOT_USER а также GITHUB_ROBOT_ACCESS_TOKEN - это переменные среды, установленные в конфигурации автоматической сборки Docker Hub.

Лично я предпочитаю зарегистрировать новую учетную запись робота с включенной 2FA на github специально для этого, пригласить учетную запись робота стать соавтором и использовать токен доступа вместо пароля, поскольку это безопаснее, чем использование вашей собственной учетной записи, которая имеет доступ к гораздо большему количеству репозиториев. чем необходимо, а также прост в управлении.

Редактировать:

Вам нужно отключить ссылку на репозиторий, иначе в Docker Hub будет много неожиданных сборочных заданий.

Если вы хотите увидеть демонстрацию этого решения, проверьте https://github.com/NobodyXu/llvm-toolchain.

Другие вопросы по тегам