Налаштування автоматичного збирання Docker-образів у CI/CD

Ручні розгортання гальмують команду й залежать від того, хто саме збирає образ. Ми налаштовуємо автоматичне збирання Docker-образів у конвеєрі під ключ: від підготовки репозиторію до передавання готового процесу вашій команді. Час на випуск нової версії скорочується в рази, а людські помилки під час збирання зникають із процесу.
Часті запитання

Автоматична збірка Docker-образів: де ламається процес

Автоматична збірка Docker-образів ламається не на етапі написання файлу збірки, а пізніше — коли реліз потрібно повторити через місяць або підняти стенд з нуля.

Найчастіша причина — збірка на машині розробника: локальні змінні середовища, розпаковані поруч каталоги, залежності, не зафіксовані в репозиторії. Образ виходить відтворюваним рівно один раз і тільки в автора — у колеги він збирається інакше, на сервері — знову інакше.

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

Ручне розгортання релізу додає до цього людський фактор: образ збирається вручну перед розгортанням, тег ставиться «на око», і за записом у реєстрі вже не зрозуміти, який саме код лежить у цьому образі.

Довгий випуск релізу — прямий наслідок такої схеми. Поки збірка не запущена, правки накопичуються у гілці, вікно розгортання зсувається, а перевірка займає години замість хвилин.

Відкат теж не відпрацьований: попередній образ або не збережений, або позначений так, що не відрізняється від проміжних збірок, — повернутися до робочого стану швидко нема чим.

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

Що змінюється після переведення збірки на конвеєр

Перший ефект — час випуску релізу. Поки збірка запускалася руками, між правкою й готовим артефактом минали години; після переведення на конвеєр кожне відправлення змін до основної гілки саме запускає збірку, перевірки та публікацію. Типовий цикл займає десятки хвилин разом із прогоном тестів.

Відтворюваність збірки перестає залежати від того, у кого що встановлено. Кроки описані декларативно, версії базового шару й залежностей зафіксовані, проміжні шари перевикористовуються — повторні збірки йдуть швидше, але результат від цього не змінюється. Один і той самий набір команд на збірному агенті та на локальній машині дає ідентичний образ.

Розмір образу падає завдяки багатоступеневій збірці: усе зайве залишається на проміжному шарі, у фінальний потрапляє лише те, що потрібно під час роботи застосунку.

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

Відкат релізу стає перемиканням на попередній образ. Кожен випуск позначений тегом і контрольною сумою, артефакт незмінний, тому попередній робочий випуск піднімається без перезбірки — хвилини замість повторного прогону всього циклу.

Повторюваність середовищ закривається тим самим механізмом: тестовий контур, передпродуктив і продуктив отримують ідентичний образ і відрізняються лише зовнішніми параметрами.

Зникає цілий клас відмов виду «на тесті працювало» та розходжень через пакети, доустановлені на сервері вручну.

Де запускати конвеєр: агенти, контейнери, свої сервери

Вибір майданчика для збірки визначає три речі: скільки часу минає від коміту до готового образу, наскільки відтворювана збірка і що станеться, коли хостинг впреться у свої ліміти. Нижче — варіанти, між якими реально обирають на практиці, з їхніми обмеженнями.

Варіант Коли підходить Обмеження
Керовані агенти провайдера Невелика команда, своєї інфраструктури немає, потрібен швидкий старт Ліміт одночасних задач, таймаут на крок, кеш шарів не переживає зміну машини
Свій сервер збірки Великі образи, приватні залежності, важкі перевірки Обслуговування, оновлення й моніторинг на нас; при відмові черга зупиняється повністю
Конвеєр у контейнері Потрібне ізольоване середовище збірки на спільному хості Вкладена збірка потребує окремого демона або розширених прав, складніше рахувати диск
Збірка на тому самому хості, що й робочий сервіс Внутрішні утиліти, швидка перевірка гіпотез Ресурси конкурують із продуктивом, ризик завалити сервіс разом зі збіркою

Найчастіше виходить гібрид: рутинні гілки йдуть на керовані агенти, а релізні образи збираються на своєму сервері з постійним кешем шарів.

Тоді ізольоване середовище збірки однакове для всіх гілок, обмеження хостингу перестають бути точкою відмови, а за потреби конвеєр переноситься на інший майданчик без переписування кроків.

Етапи впровадження конвеєра: від аудиту до передачі

Збирати образи руками на робочій машині можна, поки реліз один на тиждень. Щойно сервісів і гілок стає більше, збірка переїжджає в конвеєр — і питання вже не «чи потрібна автоматизація», а в якому порядку її впроваджувати, щоб не зламати поточні релізи.

Нижче — послідовність, за якою ми ведемо проєкт: кожен етап закінчується перевірюваним результатом, а не звітом.

  1. Аудит репозиторію. Розбираємо структуру гілок, залежності між сервісами, хто і як збирає Docker-образи зараз. Фіксуємо вузькі місця: ручні кроки, відсутність кешу, різні базові образи в різних команд.
  2. Схема конвеєра. Узгоджуємо, що запускається при коміті в гілку, що — при релізному тезі, де збірка зупиняється при падінні тестів. Схему фіксуємо до налаштування, щоб не переробляти кроки по ходу.
  3. Налаштування кроків збірки. Включаємо кеш шарів, задаємо правила тегування, розділяємо збірку й публікацію в реєстр. На виході — однаковий образ з одного й того самого коміту в будь-якого інженера.
  4. Перевірка на передпродуктивному середовищі. Прогоняємо реальний реліз новим конвеєром, звіряємо результат із ручною збіркою, перевіряємо відкат на попередній тег. Дефекти ловимо тут, а не на продуктивному середовищі.
  5. Регламенти. Описуємо тригери, змінні середовища, порядок відкату й доступи до секретів — щоб правила не жили лише в голові одного інженера.
  6. Передача документації. Віддаємо схему конвеєра, файли конфігурації та інструкцію щодо типових збоїв, разом проходимо один реліз від коміту до публікації.

Після передачі ваша команда веде конвеєр самостійно: правки в кроки збірки вносяться без звернення до нас. Супровід залишається опцією, а не умовою працездатності.

Що залишається в репозиторії та у команди після впровадження

Впровадження закінчується не працюючим конвеєром, а набором артефактів, за якими його можна відтворити, передати й обслуговувати без автора. Нижче — що саме залишається в репозиторії та в документації команди після здачі.

  • Файли конфігурації конвеєра — декларативний опис етапів прямо в репозиторії: збірка образу, перевірки, публікація в реєстр, розгортання за середовищами. Версіонуються разом із кодом, будь-яка зміна проходить рев’ю.
  • Правила доступу та ролі — хто править конфігурацію, хто запускає розгортання в промислове середовище, де лежать секрети до реєстру і як вони ротуються, термін життя токенів.
  • Схема проходження релізу — від коміту до працюючого контейнера: які перевірки обов’язкові, де потрібне ручне підтвердження, які теги присвоюються образу і які з них вважаються стабільними.
  • Інструкція для чергової зміни — що дивитися при падінні збірки, як відрізнити помилку коду від помилки середовища, до кого йде ескалація і що фіксується в журналі чергування.
  • Регламент відкату — скільки останніх образів зберігається, як виконується повернення на попередній, хто ухвалює рішення і за який час середовище повертається в робочий стан.
  • Базові образи та кеш шарів — зафіксовані базові образи й порядок шарів, щоб збірка не залежала від зовнішніх оновлень і вкладалася в передбачуваний час.
  • Метрики конвеєра — час збірки, частка успішних прогонів, частка шляхів, покритих перевірками: за ними видно деградацію до того, як вона дійде до випуску.

Такий комплект дозволяє передати супровід іншій зміні або підряднику без усних пояснень: конвеєр відтворюється за репозиторієм, а поведінка при збої описана заздалегідь.

Кейс: нестабільні розгортання у сервісу з кількома командами

Що ламалося до

Чотири команди працювали в одному репозиторії та збирали образи вручну, кожна зі своєї гілки. Розгортання відбувалося під одним плаваючим тегом: дві збірки з різницею в хвилини перезаписували артефакт одна одної, і в прод їхав образ із залежностями сусіднього сервісу. Шари не кешувалися, пакети підтягувалися заново при кожній збірці.

Половинчастою була не лише швидкість. Успішним з першого разу виявлялося приблизно кожне друге розгортання, розбір збійного релізу займав від пів години, а відкат робили руками за інструкцією з листування — і він не завжди повертав попередню робочу версію.

Що змінили і що отримали

Зібрали єдиний конвеєр у GitLab CI: збірка стартує на злиття в основну гілку, у кожного сервісу своя стадія з ізольованим кешем шарів, ключ рахується за хешем файлу залежностей.

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

  • Частка розгортань без переробок: з половини до 9 із 10.
  • Час від злиття до готового образу: з 25–40 хвилин до 6–8.
  • Відкат: однією командою на попередній тег, близько двох хвилин замість ручного розбору.
  • Розмір образу: скоротився втричі завдяки багатостадійній збірці та чищенню кешу пакетів.

Релізний цикл перестав залежати від того, хто першим натиснув збірку: команди розгортаються паралельно і не блокують одна одну.

Чим відрізняється кеш шарів від кешу залежностей

У Docker кеш шарів — це про інструкції збірки. Кожна інструкція дає незмінний шар, і поки не змінився він сам або будь-який попередній, наступні запуски перевикористовують готові шари за ланцюжком.

Тому інвалідація кешу каскадна: правка одного рядка на початку файлу збірки обнуляє все, що описано нижче.

Кеш залежностей — це окреме сховище вже завантажених бібліотек і модулів: проксі-кеш реєстру пакетів або том на збірному агенті.

Він не прив’язаний до порядку інструкцій і спільний для всіх гілок — та сама бібліотека віддається з нього повторно, а термін її життя задає політика зберігання.

Різниця проявляється на порядку кроків. Якщо спочатку копіювати маніфест залежностей і виконувати встановлення, а вихідні коди копіювати останнім шаром, правка коду перезбирає один шар.

Якщо навпаки — будь-яка зміна в коді обнуляє встановлення залежностей, і повторна збірка знову тягне весь набір пакетів.

Швидкість повторної збірки відрізняється кратно: при теплому кеші шарів і заповненому кеші залежностей агент не ходить у зовнішню мережу, і збірка займає секунди замість хвилин.

Плата за це — версіонування й регулярне чищення другого кешу: застарілі пакети й витік доступів до приватних реєстрів трапляються саме тут.

Підсумок: кеш шарів відповідає за те, що вже зібрано, кеш залежностей — за те, що вже завантажено. Першим керують через порядок інструкцій, другим — через політику зберігання й версіонування маніфесту.

Технічні сумніви перед переведенням на конвеєр

Заперечення перед переведенням автоматичної збірки docker-образів на конвеєр стосуються не самого інструмента, а того, що навколо: доступів, секретів і поведінки при збої. Нижче — короткі відповіді на те, що інженери запитують найчастіше.

Що при недоступності реєстру образів?

Конвеєр розрізняє «збірка впала» і «артефакт нікуди покласти»: у другому випадку тег не публікується, задача призупиняється, а розгортання живе на попередній версії. Реєстр дублюємо дзеркалом.

Як розділяються права випуску?

Збірка й публікація — різні ролі: розробник запускає збірку своєї гілки, а тег в основному реєстрі ставить лише конвеєр після перевірок. Перезаписати робочий образ з локальної машини більше не можна.

Де зберігаються секрети збірки?

Значення підставляються в крок збірки зі сховища секретів, у шари образу не потрапляють і маскуються в логах. Доступ до сховища має конвеєр, а не кожен розробник.

Чи не зупиниться розгортання на час переходу?

Ідемо гілка за гілкою: спочатку конвеєр збирає рівно те, що збирали руками, результат звіряємо за контрольною сумою. Поки йде звірка, ручний випуск залишається робочим — вікна простою немає.

Чому конвеєр часто падав у нас раніше?

Причина зазвичай не в конвеєрі, а в некерованих залежностях: плаваючі теги базових образів, різні версії збирача на агентах, перевикористання шарів між збірками не налаштовано. Фіксуємо залежності за контрольною сумою і робимо агентів відтворюваними — падіння стають поодинокими.

Сумнів, якого немає в списку, розберемо на вашій конфігурації.

Обговоримо задачу і повернемося з планом впровадження

Перша розмова — не презентація, а розбір того, як у вас зараз збираються й доставляються образи.

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

За цими даними видно вузькі місця і зрозуміло, що автоматизується одразу, а що потребує перебудови схеми.

Щоб повернутися з оцінкою та планом впровадження, зазвичай потрібно від замовника:

  • опис того, як збірка запускається сьогодні — вручну чи скриптом на окремій машині;
  • відомості про реєстр образів і про те, як до нього потрапляють артефакти;
  • склад середовищ і обов’язкові перевірки перед публікацією;
  • як влаштовані права й секрети: хто і що може збирати та публікувати;
  • режим роботи команди: скільки збірок на день і який час від зміни в коді до готового образу вважається нормальним;
  • що вже пробували і чому рішення не прижилося.

Далі фіксуємо порядок робіт: описуємо цільову схему збірки й політику тегування, налаштовуємо її на тестовій гілці, потім переносимо на інші середовища й передаємо документацію з регламентом відкату.

Терміни та етапи узгоджуємо заздалегідь — кожен етап закінчується робочим результатом, який можна перевірити на своїх задачах. Опишіть задачу й поточну схему збірки — повернемося з планом впровадження.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1543
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1374
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142