Community
1
HostiServer
2026-08-07 08:03

Self-hosted CI/CD: концепція, архітектура і runner'и

⏱️ Час читання: ~13 хвилин | 📅 Оновлено: серпень 2026

Self-hosted CI/CD: концепція, архітектура і runner'и

У першій частині серії ми розібрали, що таке CI/CD, з чого складається pipeline і чим Continuous Delivery відрізняється від Continuous Deployment. Там залишилося одне питання без відповіді: а на якій, власне, машині виконуються всі ці збірки і тести?

За замовчуванням відповідь проста: на чужій. Ви пишете runs-on: ubuntu-latest, і GitHub піднімає для вас віртуальну машину, ганяє на ній ваш код, а потім знищує її. Це зручно рівно до того моменту, коли починають заважати ліміти, вартість або вимоги до того, де саме має виконуватися ваш код. Тоді на сцену виходить self-hosted runner: власна машина, яка робить ту саму роботу, але під вашим контролем.

Ця стаття не про встановлення (це буде у частинах 3, 4 і 5 для GitHub Actions, GitLab CI і Gitea Actions відповідно), а про архітектуру: як runner улаштований, чому він не потребує відкритих портів, які бувають executor-и, скільки ресурсів реально потрібно і які помилки у налаштуванні перетворюють ваш runner на відкриті двері в інфраструктуру.

1.1 Хмарні runner'и: як це працює за замовчуванням

Коли pipeline виконується на інфраструктурі платформи, кожна задача отримує чисту віртуальну машину з попередньо встановленим набором інструментів: компілятори, Docker, типові SDK, кеш популярних образів. Після завершення задачі машина знищується разом з усіма даними.

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

  • Ліміти хвилин. Безкоштовна квота скінченна, і зростає вона не так швидко, як кількість pipeline.
  • Вартість при великому обсязі. Хвилини понад квоту оплачуються, і рахунок росте лінійно від кількості збірок.
  • Закритий контур. Код і секрети виконуються на чужій інфраструктурі. Для частини проєктів це неприйнятно за договором або регламентом.
  • Фіксовані ресурси. Стандартний runner це 2 vCPU і кілька гігабайтів RAM. Якщо збірка вимагає GPU, 32 ГБ пам'яті або процесора ARM, стандартна конфігурація не підходить.

1.2 Self-hosted: власний сервер виконує задачі

Self-hosted runner це процес-агент, який ви запускаєте на власному сервері, VPS або навіть на машині у офісі. Він реєструється у вашому проєкті на GitHub або GitLab і починає отримувати звідти задачі. Вся решта не змінюється: pipeline описується тим самим YAML, логи і статуси видно у тому самому інтерфейсі, кнопки і сповіщення працюють як раніше.

Змінюється лише одне: рядок з вибором runner-а у конфізі pipeline.

# GitHub Actions: замість ubuntu-latest
jobs:
build:
runs-on: [self-hosted, linux, x64]

# GitLab CI: задача піде на runner з відповідним тегом
build:
tags:
- self-hosted

Важливо розуміти межу відповідальності. Платформа лишається у себе: репозиторій, інтерфейс, черга задач, зберігання секретів, артефакти. Ви берете на себе тільки виконання: машину, її ресурси, оновлення ОС, ізоляцію і безпеку. Це не заміна GitHub або GitLab на власний сервер, а перенесення однієї конкретної частини системи ближче до себе.

2. Коли self-hosted виправданий

Власний runner це не «правильніше» і не «дорослий рівень». Це компроміс: ви отримуєте контроль і передбачувану вартість, натомість берете на себе адміністрування. Нижче чотири ситуації, у яких цей обмін вигідний.

2.1 Вичерпані безкоштовні хвилини

Це найчастіша причина. Актуальні на середину 2026 року квоти виглядають так:

Платформа Безкоштовно Понад квоту Власний runner
GitHub Actions, публічні репозиторії Без обмежень Безкоштовно
GitHub Actions, приватні (план Free) 2000 хв/міс (Linux) $0.006/хв за Linux 2-core Безкоштовно
GitLab.com (план Free) 400 хв/міс на групу $10 за 1000 хвилин Безкоштовно, без обліку хвилин

Дві деталі, які регулярно стають несподіванкою. Перша: у GitHub квота витрачається з множником залежно від ОС, тобто збірка на Windows з'їдає удвічі більше квоти за той самий час, а на macOS удесятеро. Друга: у GitLab безкоштовні хвилини рахуються на всю групу верхнього рівня, а не на користувача чи проєкт, тому команда з п'яти осіб і команда з п'ятдесяти стартують з тієї самої цифри.

⚠️ Тарифи змінюються: наприкінці 2025 року GitHub анонсував платіж за самі хвилини self-hosted runner-ів (плата за оркестрацію), а після реакції спільноти відклав його на невизначений термін, і станом на середину 2026 виконання на власних runner-ах лишається безкоштовним. Це нормальна динаміка ринку, тому перед плануванням бюджету звіряйтеся з актуальними сторінками тарифів обох платформ.

2.2 Закритий контур

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

Тут важливо розуміти нюанс. Self-hosted runner сам по собі не робить контур закритим: якщо репозиторій живе на GitHub.com, код і так уже там. Власний runner вирішує іншу задачу — щоб виконання відбувалося у вашому периметрі: збірка з доступом до внутрішніх пакетних репозиторіїв, тести проти бази у приватній мережі, деплой на сервери, які не мають публічної адреси. Повністю закритий контур це вже self-hosted git-платформа (GitLab CE, Gitea, Forgejo) плюс власні runner-и.

Практичний бонус тієї самої властивості: runner всередині вашої мережі має доступ до продакшн-серверів по приватних адресах, і вам не потрібно відкривати SSH назовні заради деплою.

2.3 Специфічне залізо і оточення

Стандартні runner-и платформ це універсальні Linux-машини середньої потужності. Якщо ваша задача виходить за ці рамки, власний runner часто єдиний варіант:

  • GPU для навчання і тестування моделей або для збірки з CUDA.
  • ARM для нативної збірки під ARM-сервери, Raspberry Pi або мобільні платформи. Емуляція через QEMU працює, але у рази повільніша.
  • Конкретна версія ОС: збірка пакета під CentOS 7 або тестування на ядрі, якого немає у стандартних образах.
  • Багато RAM: збірка великого монорепозиторію або інтеграційні тести, які піднімають десяток сервісів одночасно.
  • Швидкий локальний кеш: NVMe з прогрітим кешем залежностей і шарів Docker дає прискорення, якого не буде на чистій машині щоразу.

2.4 Вартість: рахунок замість відчуттів

Порівняння має сенс лише на конкретних цифрах. Візьмемо команду, яка робить 60 збірок на день по 10 хвилин, тобто приблизно 13 000 хвилин на місяць:

Варіант Розрахунок На місяць
GitHub Actions, план Free (13 000 − 2000) × $0.006 ~$66
GitLab.com, план Free (13 000 − 400) × $0.01 ~$126
Власний runner на VPS вартість VPS, хвилини не рахуються від ~$20

Для маленького проєкту з кількома збірками на день картина протилежна: безкоштовної квоти вистачає з запасом, і платити за VPS немає сенсу. Точка беззбитковості у більшості команд настає між 3000 і 10 000 хвилин на місяць, залежно від платформи і того, наскільки важкі збірки.

І одразу чесне застереження: «безкоштовно» у колонці власного runner-а стосується лише хвилин. Реальна вартість це VPS плюс час інженера на початкове налаштування і подальше обслуговування (оновлення ОС, чищення диска, оновлення самого агента). Для однієї машини це кілька годин на старті і приблизно година на місяць далі. Якщо ваша економія на хвилинах менша за цю годину, лишайтеся на хмарних runner-ах.

3. Як влаштований runner

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

3.1 Модель polling: runner сам іде за завданнями

Ключова архітектурна властивість: платформа ніколи не підключається до runner-а. Усе навпаки. Після реєстрації агент відкриває вихідне HTTPS-з'єднання до платформи і тримає його, періодично запитуючи наступну задачу. GitLab Runner робить це запитом до API з інтервалом у кілька секунд, агент GitHub тримає довге з'єднання і чекає на призначення задачі.

Модель polling: runner сам відкриває вихідне з'єднання до платформи і запитує задачі

З цього випливають три практичні наслідки:

  • Не потрібен публічний IP і відкриті порти. Runner працює за NAT, у домашній мережі, за корпоративним firewall.
  • Не потрібен вхідний трафік взагалі. Для firewall це означає: вхідні з'єднання заборонені повністю, крім вашого SSH для адміністрування.
  • Runner переживає розрив зв'язку. Після відновлення мережі він просто продовжить опитування, а платформа поставить задачу у чергу і дочекається вільного агента.

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

3.2 Що відбувається всередині задачі

Коли платформа призначає задачу, агент проходить один і той самий цикл:

  1. Отримання опису задачі. Репозиторій, коміт, змінні оточення, список кроків і тимчасовий токен доступу, який діє лише поки триває задача.
  2. Підготовка робочої директорії. Створення або очищення workspace, підняття контейнера (якщо executor контейнерний), підключення сервісних контейнерів на кшталт бази даних для тестів.
  3. Checkout. Отримання коду з тимчасовим токеном, зазвичай неглибоке клонування для швидкості.
  4. Виконання кроків. Команди виконуються послідовно, кожна у своєму процесі. Ненульовий код повернення зупиняє задачу, якщо крок явно не позначено як необов'язковий.
  5. Стрімінг логів. Вивід передається на платформу частинами під час виконання, тому лог видно у реальному часі, а не після завершення.
  6. Артефакти і кеш. Указані файли пакуються і завантажуються у сховище платформи, кеш зберігається для наступних запусків.
  7. Завершення і прибирання. Агент повідомляє статус і звільняється під наступну задачу.

⚠️ Останній крок найважливіший для self-hosted: на хмарному runner-і машина знищується разом з усім, що на ній залишилося. На вашому сервері нічого не знищується само собою. Залишки попередніх збірок, розрослий кеш, запущені у фоні контейнери, глобально встановлені пакети — усе це накопичується і рано чи пізно дає збірку, яка «раптом зламалася без змін у коді». Прибирання доводиться налаштовувати свідомо, і саме на цьому найчастіше спотикаються при переході на власні runner-и.

3.3 Executor'и: де саме виконуються команди

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

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

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

# config.toml для GitLab Runner з Docker executor
concurrent = 4
check_interval = 3

[[runners]]
name = "build-01"
url = "https://gitlab.com/"
token = "glrt-..."
executor = "docker"
[runners.docker]
image = "alpine:3.20"
privileged = false
volumes = ["/cache"]

Kubernetes. Кожна задача це окремий pod у кластері. Дає автоматичне масштабування під навантаження і природну ізоляцію, але має сенс лише там, де кластер уже є і його є кому обслуговувати.

Executor Ізоляція Складність Коли обирати
Shell Немає Мінімальна Приватний репозиторій, довірений код, прості задачі
Docker Процеси і ФС Середня Типовий вибір для більшості проєктів
Kubernetes Pod на задачу Висока Є кластер і потрібне масштабування
Executor-и runner-а: shell, Docker і Kubernetes та рівень ізоляції кожного

У GitHub Actions термінології executor-ів немає: агент за замовчуванням виконує кроки на хості (аналог shell), а контейнеризація вмикається на рівні задачі ключем container:. Для кластерів існує окремий компонент, який створює одноразові runner-и у Kubernetes.

ℹ️ Docker всередині Docker: найпоширеніша складність з контейнерним executor-ом виникає тоді, коли pipeline сам збирає Docker-образ. Класичні рішення це запуск контейнера у privileged-режимі або підключення сокета Docker з хоста, і обидва фактично дають задачі права root на самому сервері. Безпечніші варіанти це інструменти збірки образів без демона (Kaniko, Buildah, BuildKit у rootless-режимі) або окремий ізольований сервер збірки, який не має доступу ні до секретів продакшну, ні до приватної мережі.

4. Вимоги до інфраструктури

4.1 Скільки ресурсів реально потрібно

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

Профіль навантаження vCPU / RAM Диск
Лінтери, модульні тести, легкі скрипти 1 / 1 ГБ 20 ГБ
Збірка фронтенду, Docker-образи, інтеграційні тести 2 / 4 ГБ 50-80 ГБ
Монорепозиторій, паралельні задачі, e2e у браузері 4-8 / 8-16 ГБ 100+ ГБ

Найчастіше недооцінюють саме диск. Docker-образи, кеш шарів, завантажені залежності і артефакти ростуть непомітно, і перша аварія на власному runner-і у більшості команд це не брак пам'яті, а no space left on device посеред збірки. Закладайте автоматичне прибирання за розкладом і моніторинг вільного місця з першого дня.

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

4.2 Мережа: тільки вихідні з'єднання

Для роботи runner-у потрібен лише вихідний HTTPS до платформи і до тих ресурсів, звідки він тягне залежності: реєстри пакетів, реєстри образів, дзеркала дистрибутива. Вхідні порти не потрібні жодні.

Мінімальна розумна конфігурація firewall на сервері runner-а:

# вхідні: тільки SSH для адміністрування, краще з відомих адрес
ufw default deny incoming
ufw default allow outgoing
ufw allow from 203.0.113.0/24 to any port 22 proto tcp
ufw enable

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

4.3 Один runner чи кілька

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

Паралелізм досягається двома способами. У GitLab Runner один процес може обслуговувати кілька задач одночасно: параметр concurrent у config.toml задає загальну кількість. У GitHub Actions один агент це одна задача, тому для паралельного виконання запускають кілька агентів, у тому числі на одній машині.

Практичне правило: одна паралельна задача на кожні 2 vCPU. Ставити concurrent = 8 на дводядерному VPS немає сенсу, бо задачі почнуть конкурувати за процесор і кожна виконуватиметься довше, ніж якби вони йшли по черзі.

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

5. Безпека: головні принципи

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

5.1 Не підключайте власний runner до публічних репозиторіїв

Це головне правило, і воно не має винятків для новачків. Обидві платформи прямо не рекомендують використовувати self-hosted runner-и у публічних проєктах, і причина фундаментальна: будь-яка стороння людина може створити форк вашого репозиторію, змінити файл pipeline і відкрити pull request. Якщо ваш runner візьме цю задачу, він виконає чужий код на вашому сервері.

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

Якщо власний runner для публічного проєкту все ж потрібен (наприклад, збірка під ARM), обов'язковий мінімум це одноразові (ephemeral) runner-и, які знищуються після кожної задачі, ізольована мережа без доступу до чогось цінного і обов'язкове ручне підтвердження запуску pipeline для pull request із зовнішніх форків.

5.2 Docker executor як мінімальний рівень ізоляції

Контейнер це не повноцінна пісочниця, але це набагато краще за виконання команд прямо на хості. Мінімальний набір вимог:

  • Без privileged. Привілейований контейнер це фактично права root на хості.
  • Без монтування сокета Docker. Доступ до /var/run/docker.sock дозволяє задачі запустити контейнер з примонтованим кореневим розділом хоста.
  • Обмеження ресурсів. Ліміти CPU і пам'яті на контейнер, щоб одна задача не поклала весь сервер.
  • Свіжий стан. Кожна задача стартує з нового контейнера, без перевикористання попереднього.

5.3 Окремий системний користувач з мінімальними правами

Агент ніколи не повинен працювати від root. Створіть окремого системного користувача, від імені якого працює служба:

sudo useradd --system --create-home --shell /bin/bash ci-runner
# без sudo, без доступу до чужих домашніх директорій
sudo chmod 750 /home/ci-runner

Далі за списком: у цього користувача немає прав sudo, робоча директорія належить лише йому, служба запускається через systemd від його імені, а SSH-ключі для деплою (якщо вони тут потрібні) видані окремому обмеженому користувачу на цільовому сервері, а не root.

5.4 Секрети тільки через механізм платформи

У репозиторії не повинно бути жодного пароля, токена чи ключа. Секрети зберігаються у механізмі платформи (Secrets у GitHub, CI/CD Variables у GitLab) і потрапляють у задачу як змінні оточення на час її виконання.

Кілька правил, які варто застосувати одразу:

  • Маскування у логах. Обидві платформи вміють приховувати значення секретів у виводі. Це не захист від навмисного витягування, але рятує від випадкового echo.
  • Прив'язка до захищених гілок. Секрети продакшну доступні лише задачам із захищеної гілки або визначеного середовища, а не будь-якій гілці будь-якого розробника.
  • Мінімальні права. Токен для деплою вміє тільки деплоїти. Ключ SSH прив'язаний до одного користувача і, за потреби, до однієї дозволеної команди.
  • Ротація. Секрети змінюються після звільнення людини з доступом і після будь-якого підозрілого інциденту з runner-ом.

⚠️ Головне про секрети на self-hosted runner-і: під час виконання задачі секрет лежить у змінних оточення процесу на вашому сервері у відкритому вигляді. Це означає, що будь-хто з доступом до цієї машини (root, інший процес того самого користувача, чужий код у задачі) може їх прочитати. Тому runner з продакшн-секретами треба захищати як продакшн-сервер, а не як допоміжну машину для збірок.

6. Висновок

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

  • Коли переходити. Коли квота хвилин вичерпується щомісяця, коли виконання має відбуватися всередині вашого периметра, коли потрібне залізо, якого немає у стандартних runner-ів. Для маленького проєкту з десятком збірок на день хмарні runner-и дешевші і простіші.
  • Мережа. Runner працює на вихідних з'єднаннях, тому не потребує публічного IP і відкритих портів. Це одночасно і зручно, і безпечно.
  • Ресурси. Починати можна з 1 vCPU і 1 ГБ RAM, реалістичний робочий мінімум для збірок з Docker це 2 vCPU, 4 ГБ і 50 ГБ диска. Диск і прибирання після задач важливіші, ніж здається на старті.
  • Безпека. Ніяких публічних репозиторіїв без ізоляції, Docker executor без privileged, окремий користувач без sudo, секрети лише через платформу і лише для захищених гілок.

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

Що далі у серії

Архітектура у обох платформ спільна, а реалізація помітно різна: у GitHub Actions це агент з мітками і кроками з marketplace, у GitLab CI це gitlab-runner з тегами, executor-ами і власним конфігом. Тому наступні дві частини практичні і паралельні за структурою.

У третій частині ставимо власний runner для GitHub Actions на VPS і збираємо перший робочий pipeline: реєстрація агента, служба systemd, структура workflow, кеш. У четвертій те саме для GitLab CI: gitlab-runner, executor-и, .gitlab-ci.yml, стадії і правила. П'ята частина про Gitea Actions, коли git-платформа і pipeline живуть на одному власному сервері. Шоста підсумовує серію порівнянням трьох платформ і відповіддю на питання, що обирати під конкретні умови.

📚 Навігація по серії:
← Попередня: Частина 1. Що таке CI/CD: від ручного deploy до автоматизованих pipelines
Ви читаєте частину 2 з 6 «Self-hosted CI/CD: концепція, архітектура і runner'и».
Наступна: Частина 3. GitHub Actions self-hosted runner: встановлення та перший pipeline на VPS →

🚀 Сервер під власний CI/CD runner

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

💻 Cloud (VPS) Хостинг

  • Від $19.95/міс, KVM-ізоляція, виділені vCPU і RAM без сусідів по ядру
  • Оптимально для першого runner-а: 2 vCPU, 4 ГБ RAM і NVMe закривають типові збірки з Docker
  • Приватна мережа між runner-ом і вашими продакшн-серверами
  • Масштабування за хвилини: додати ресурси або ще один runner під зростання команди

🖥️ Виділені Сервери

  • Від $90/міс, повний контроль над залізом для важких і паралельних збірок
  • NVMe і багато RAM: прогрітий кеш залежностей і шарів Docker замість завантаження щоразу
  • Кілька runner-ів на одній машині: окремо збірка, окремо деплой, з розділенням прав

💬 Не впевнені, який варіант вам необхідний?
💬 Напишіть нам і ми зі всім допоможемо!

Часті питання

Чи можна поставити runner на той самий сервер, де працює продакшн?

Технічно можна, практично не варто. Три причини. Перша: збірка це стрибки навантаження на CPU і диск, тобто продакшн-сервіс отримуватиме просідання швидкодії у випадкові моменти. Друга: збірки заповнюють диск, і no space left on device покладе не тільки pipeline, а й застосунок. Третя і головна: код з репозиторію виконуватиметься на машині з продакшн-даними, і будь-яка помилка у pipeline або скомпрометована залежність одразу опиняється поруч з базою. Мінімально прийнятний компроміс для дуже маленького проєкту це окремий системний користувач і жорсткі ліміти ресурсів через systemd, але окремий VPS дешевший за наслідки.

Скільки задач витримає один VPS?

Орієнтир простий: одна паралельна задача на кожні 2 vCPU за умови, що вистачає пам'яті і диска. На VPS з 2 vCPU і 4 ГБ комфортно працює одна збірка з Docker, дві вже конкуруватимуть за ресурси. Обмежувальним фактором частіше стає не процесор, а диск: паралельні задачі одночасно тягнуть образи і пишуть кеш. Якщо збірки короткі і рідкісні, черга з одного агента нікому не заважає, і збільшувати паралелізм немає потреби.

Чи безпечно давати runner-у SSH-доступ до продакшну?

Це нормальна практика за умови мінімальних прав. Робочий мінімум: окремий користувач на цільовому сервері замість root, окремий SSH-ключ саме для деплою (не особистий ключ інженера), доступ по приватній мережі, а не через публічну адресу, і обмеження ключа у authorized_keys опціями command=, no-port-forwarding, no-agent-forwarding. Тоді навіть при компрометації runner-а зловмисник отримує право запустити один конкретний скрипт деплою, а не інтерактивну сесію. Окремо: деплой-ключ повинен лежати на runner-і для деплою, а не на runner-і для тестів.

Що робити з диском, який забивається Docker-образами?

Планувати прибирання з першого дня, а не після першої аварії. Робочий набір: регулярний docker system prune за розкладом (наприклад, щоночі, зі збереженням свіжого кеша), обмеження часу життя кеша збірки, видалення старих робочих директорій задач, моніторинг вільного місця з алертом на 80%. Корисно розділити диск так, щоб робоча директорія runner-а і сховище Docker були на окремому розділі: тоді переповнення не покладе систему цілком і сервер лишиться керованим.

Чи витрачає власний runner безкоштовні хвилини платформи?

Станом на середину 2026 року ні: у GitLab виконання на власних runner-ах не списує compute-хвилини взагалі, у GitHub self-hosted runner-и не тарифікуються. GitHub наприкінці 2025 року анонсував плату за оркестрацію self-hosted хвилин у приватних репозиторіях, але відклав її на невизначений термін. Оскільки такі умови змінюються, при плануванні бюджету перевіряйте актуальні сторінки тарифів обох платформ.

Чи потрібен статичний IP або відкриті порти для runner-а?

Ні. Агент сам ініціює вихідне HTTPS-з'єднання до платформи і чекає задачі, тому працює за NAT і за firewall без жодних вхідних дозволів. Вам потрібен лише вихід у мережу до платформи, до реєстрів пакетів і образів, до дзеркал дистрибутива. Вхідний доступ потрібен тільки вам самим для адміністрування по SSH, і його варто обмежити відомими адресами. Якщо ваша політика забороняє довільні вихідні з'єднання, доведеться скласти список дозволених доменів платформи з її документації.

Що таке ephemeral runner і коли він потрібен?

Це агент, який виконує рівно одну задачу і після цього завершується, а на його місце піднімається новий екземпляр. Так відтворюється головна властивість хмарних runner-ів: кожна збірка починається у чистому середовищі, і нічого від попередньої задачі не залишається. Потрібен він у двох випадках: коли задачі виконують код, якому ви довіряєте не повністю, і коли збірки конфліктують між собою через залишковий стан. Ціна це трохи довший старт кожної задачі і потреба в механізмі, який автоматично піднімає нові екземпляри. Реалізація відрізняється між платформами: у GitHub це окремий прапорець при реєстрації агента, у GitLab автоматичне створення екземплярів під навантаження.

Contents

Поділіться цією статтею

VPS з підтримкою від

$19 95 / міс

Виділені сервери від

$80 / міс

CDN починаючи від

$0 / міс

 

Користуючись цим сайтом, ви погоджуєтеся на використання файлів cookies відповідно до нашої Політики Конфіденційності.