14 липня 2026 р.
Налаштування GitHub Actions для деплойменту

GitHub Actions часто підключають тоді, коли команді потрібно прибрати ручний деплой, зменшити кількість помилок під час релізу й отримати передбачуваний сценарій оновлення сервісу. Проблема в тому, що багато перших конфігурацій працюють лише в ідеальних умовах: один репозиторій, один сервер, один секрет і жодної перевірки перед запуском. Як тільки з'являються окремі середовища, кілька гілок або потреба швидко відкотити зміну, такий workflow починає створювати більше ризику, ніж користі.
Практичний підхід до GitHub Actions для деплойменту починається не з красивого YAML, а з розуміння самого процесу: коли запускати pipeline, які кроки перевіряти до копіювання файлів, як передавати секрети, що саме робити на сервері після отримання нового коду й як не допустити ситуації, коли напівуспішний реліз лишає середовище в непередбачуваному стані. Якщо потрібне повне впровадження процесів на боці репозиторіїв, серверів і runtime, зазвичай це входить у DevOps послуги.
Що потрібно підготувати до налаштування GitHub Actions
Перед створенням workflow варто окремо визначити джерело правди для деплойменту. Найчастіше це одна гілка, наприклад `main` або `stage`, з якої запускається оновлення конкретного середовища. Якщо цього не зробити, команда швидко отримає хаос: одна людина деплоїть з feature-гілки, інша повторно запускає старий workflow, третя вручну править сервер, і ніхто вже не розуміє, яка ревізія реально працює в production або staging.
Другий обов'язковий крок це підготовка сервера. На ньому має існувати окремий користувач для деплойменту, потрібні каталоги, права доступу і зрозумілий post-deploy сценарій. Якщо після копіювання файлів ще треба вручну виконувати міграції, збірку або рестарт сервісів, це слід одразу формалізувати в окремому shell-скрипті. Саме так GitHub Actions перетворюється на відтворюваний процес, а не на набір випадкових команд. Якщо інфраструктурна частина вже потребує формалізації релізів, зручно одразу продумати побудову та оптимізацію CI/CD.
Третє питання це секрети. Не можна зберігати SSH-ключі, токени реєстру або адреси серверів прямо у workflow-файлі. Для цього використовують GitHub Secrets та, за потреби, GitHub Environments. У простому сценарії достатньо таких змінних: `DEPLOY_HOST`, `DEPLOY_USER`, `DEPLOY_PORT`, `DEPLOY_PATH`, `SSH_PRIVATE_KEY`. Якщо є кілька середовищ, краще розділяти їх окремими наборами змінних і не намагатися вмістити всю логіку в один monolithic workflow.
Базова структура workflow для деплойменту
Найпрактичніша стартова структура складається з трьох частин: checkout коду, короткої перевірки або збірки, а потім безпосередньо деплойменту на сервер. Такий поділ дає можливість рано зупинити pipeline, якщо збірка або тести вже показали проблему.
name: Deploy application
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Run build
run: npm run buildЦе лише каркас. Справжня користь з'являється тоді, коли після локальної збірки pipeline безпечно передає артефакти на сервер і викликає вже підготовлений деплой-скрипт. Для невеликих середовищ зручно або копіювати файли через `rsync`, або виконувати віддалений `git pull`, якщо на сервері вже існує робочий checkout і це відповідає вашому процесу.
Як безпечно передати доступ до сервера
Найчастіше GitHub Actions підключається до сервера через SSH-ключ. Ключ створюють окремо під деплоймент, без використання особистого доступу адміністратора. Публічну частину додають у `~/.ssh/authorized_keys` на сервері, приватну зберігають у GitHub Secrets.
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/github-actions-deploy
cat ~/.ssh/github-actions-deploy.pubПісля цього приватний ключ записують у секрет `SSH_PRIVATE_KEY`, а в workflow додають підготовку SSH-середовища.
- name: Configure SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -p ${{ secrets.DEPLOY_PORT }} ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hostsОкремо варто задати fingerprint сервера через `ssh-keyscan` ще на етапі підготовки, а не вимикати перевірку host key. Це дрібниця, яку часто ігнорують, але саме вона відділяє контрольований деплоймент від небезпечного сценарію, де pipeline готовий підключатися до будь-якого хоста з відповідною адресою.
Практичний сценарій деплойменту через rsync і віддалений скрипт
Для багатьох web-сервісів зручно копіювати репозиторій або готові файли на сервер, а далі запускати один віддалений скрипт, який уже знає, як оновити застосунок. Такий варіант дозволяє тримати operational-логіку ближче до сервера і не дублювати її всередині YAML.
- name: Sync files to server
run: |
rsync -az --delete \
--exclude ".git" \
--exclude "node_modules" \
./ \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}
- name: Run remote deploy script
run: |
ssh -p ${{ secrets.DEPLOY_PORT }} \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \
"cd ${{ secrets.DEPLOY_PATH }} && ./deploy.sh"На сервері сам `deploy.sh` краще тримати коротким і передбачуваним.
#!/usr/bin/env bash
set -euo pipefail
npm ci
npm run build
pm2 restart appЯкщо в середовищі є міграції або генерація артефактів, вони також мають бути тут, а не розкидані по різних місцях. У результаті команда отримує одну точку входу для релізу і зрозумілий список дій, який можна відлагоджувати окремо від GitHub Actions.
Окремо варто розділяти staging і production. Одна з типових помилок це спроба зробити один workflow, який однаково працює для всіх середовищ. На практиці краще або розділяти job за `environment`, або мати окремі workflow-файли. Наприклад, push у `stage` може запускати деплоймент на тестовий сервер автоматично, а production реліз виконуватися лише після ручного підтвердження через protected environment. Такий підхід важливий не лише через різні секрети. Він допомагає чітко відокремити тестове середовище від production, зменшує шанс випадкового релізу не тієї гілки і робить історію запусків зрозумілішою.
on:
push:
branches:
- stage
workflow_dispatch:
jobs:
deploy-stage:
environment: staging
runs-on: ubuntu-latestТипові помилки
Найчастіша проблема це надмірна логіка всередині одного workflow. Коли YAML одночасно збирає застосунок, готує SSH, редагує конфіги, запускає міграції, чистить кеш і робить rollback, його стає важко підтримувати. У такому випадку навіть дрібна зміна в одному кроці ризикує зламати увесь релізний ланцюжок.
Друга помилка це відсутність fail-fast перевірок. Якщо pipeline не запускає хоча б базову збірку або синтаксичну перевірку до копіювання файлів, команда дізнається про проблему вже після неповного деплойменту. Краще витратити зайві хвилини на build у CI, ніж виправляти напівоновлений сервер.
Третя помилка це спільні облікові записи й секрети без життєвого циклу. Коли один SSH-ключ використовується всюди й роками не переглядається, зростає операційний ризик. Ключі та токени треба міняти, а доступи прив'язувати до конкретного сценарію. Саме тому корисно звірити свій pipeline з уже робочими підходами з матеріалу про побудову CI/CD через GitLab Runner, навіть якщо зараз ви працюєте в GitHub, а не в GitLab.
Четверта помилка це відсутність rollback-плану. Якщо нова версія вже поїхала на сервер, а після цього виявився дефект, команда має розуміти, як швидко повернути попередній стан: через попередній тег, через попередню директорію з релізом або через повторний запуск конкретної ревізії. Без цього будь-який CI/CD залишається автоматизованим, але не керованим.
Висновок
GitHub Actions для деплойменту дає найбільший ефект тоді, коли він оформлює вже продуманий процес, а не намагається замінити його собою. Хороший workflow повинен чітко знати, звідки брати код, що перевіряти до релізу, як безпечно працювати із секретами, яким способом доставляти зміни на сервер і як поводитися при помилці.
Для старту не потрібна надскладна схема. Достатньо одного передбачуваного сценарію: checkout, build, безпечний SSH-доступ, копіювання файлів і запуск віддаленого deploy-скрипта. Але саме дисципліна в цих кроках відрізняє робочий автоматизований реліз від крихкого YAML, який доводиться боятися запускати. Якщо процес уже виходить за межі простого деплою й зачіпає середовища, секрети, rollback та масштабування, краще одразу оформлювати це як повноцінний CI/CD-контур, а не серію разових латок.