Налаштування автоматичного деплою preview-оточень у Kubernetes

Розробники витрачають години в очікуванні деплою, а тестувальники перевіряють не ту версію — staging не справляється з паралельними PR. Ми налаштовуємо автоматичний деплой preview-оточень у Kubernetes: кожен PR отримує ізольований простір, який живе лише під час рев'ю. Наша команда реалізує проєкт під ключ — від налаштування пайплайнів до підтримки, забезпечуючи стабільну роботу та масштабування разом із вашим бізнесом.
Часті запитання

Уявіть: розробник відкриває PR з правками форми оформлення замовлення. QA чекає на посилання для перевірки. Дизайнер хоче подивитися на кнопку в контексті. Тімлід не може змержити без живого рев'ю. Поки preview-оточень немає — всі чекають деплой у staging, який хтось уже зайняв іншою гілкою. У типовій команді з 10 розробників кожен PR чекає деплою в staging у середньому 2 години. З preview environment деплой займає 3 хвилини. Ми — команда DevOps-інженерів з 7+ роками досвіду в CI/CD та Kubernetes. За цей час ми розгорнули preview environments для десятків проектів — від стартапів до enterprise. Допоможемо і вам автоматизувати тестування PR. Оцінимо проект — просто напишіть нам.

Preview environments вирішують цей затор: кожен PR отримує ізольоване оточення автоматично, живе поки PR відкритий, вмирає після мержу або закриття. Це скорочує час рев'ю на 40%, знижує витрати на хмарну інфраструктуру на 30% завдяки автоматичному видаленню та виключає конфлікти ресурсів. Нижче розберемо, як побудувати систему на Kubernetes та GitHub Actions, і яких помилок уникнути.

Чому staging не підходить для паралельних PR?

Один staging на декілька активних PR — класика. Гілка feature/checkout-v2 затирає bugfix/payment-redirect, тестувальник перевіряє не те, розробник не розуміє звідки баг. У результаті staging перетворюється на вічний конфлікт ресурсів.

Друга проблема — залежності. Якщо застосунок тягне базу даних, Redis, S3 — для кожного PR потрібна ізольована копія цих сервісів або хоча б окрема схема/namespace. Без цього тести з одного PR ламають дані іншого.

Третя — час життя. Відпрацьовані PR накопичуються, оточення не чистять, хмарний рахунок зростає. Потрібна автоматична утилізація за подією closed або merged.

Як розгорнути preview environments на Kubernetes?

Типова реалізація на Kubernetes + GitHub Actions: при відкритті PR тригериться workflow, який збирає образ, пушить в registry з тегом pr-{number}, застосовує Helm-чарт у namespace preview-pr-{number} та коментує PR з посиланням на оточення.

Приклад workflow
---
# .github/workflows/preview.yml (фрагмент)
on: pull_request:
  types: [opened, synchronize, reopened, closed]
jobs:
  deploy-preview:
    if: github.event.action != 'closed'
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to preview namespace
        run: |
          helm upgrade --install \
            preview-pr-${{ github.event.number }} ./helm/app \
            --namespace preview-pr-${{ github.event.number }} \
            --create-namespace \
            --set image.tag=pr-${{ github.event.number }} \
            --set ingress.host=pr-${{ github.event.number }}.preview.example.com
  cleanup-preview:
    if: github.event.action == 'closed'
    runs-on: ubuntu-latest
    steps:
      - name: Delete preview namespace
        run: kubectl delete namespace preview-pr-${{ github.event.number }} --ignore-not-found

Для баз даних є декілька підходів. Найдешевший — окрема схема PostgreSQL на кожен PR: CREATE SCHEMA pr_519 AUTHORIZATION app_user;, застосовуються міграції, після мержу схема дропається. Не потрібні окремі поди бази. Працює якщо застосунок вміє в search_path.

Якщо потрібна повна ізоляція — ephemeral database через оператор (наприклад, CloudNativePG з шаблонами кластерів) або Neon/PlanetScale з branch per PR.

DNS та Ingress

Wildcard-сертифікат на *.preview.example.com плюс один wildcard Ingress-правило через nginx-ingress або Traefik:

---
# ingress wildcard rule - host: "*.preview.example.com"
http:
  paths:
    - path: /
      pathType: Prefix
      backend:
        service:
          name: preview-router # роутить за hostname на потрібний сервіс

Або cert-manager з Let's Encrypt DNS-01 challenge виписує wildcard автоматично.

Альтернативи Kubernetes

Якщо кластера немає — Render, Railway, Fly.io вміють preview environments нативно. Vercel та Netlify роблять це з коробки для статики та Next.js. Для більш важких застосунків — Uffizzi або Namespace (колишній Shipyard): розгортають оточення в ефемерних кластерах без обслуговування інфраструктури з вашого боку.

Docker Compose-based підхід: кожен PR запускає docker compose up на виділеному runner-і з проброскою порту через Cloudflare Tunnel або ngrok. Дешево, але не масштабується вище ~10 одночасних PR.

Як уникнути конфліктів баз даних у preview?

Найнадійніший спосіб — використовувати окремі схеми в PostgreSQL для кожного PR. Застосунок має динамічно вибирати схему через змінну оточення SEARCH_PATH. Це дає ізоляцію даних без запуску додаткових контейнерів. Альтернатива — ephemeral база даних на основі CloudNativePG: кожен PR отримує міні-кластер, який живе рівно стільки ж, скільки й namespace. Такий підхід дорожчий, але забезпечує повну ізоляцію на рівні інстансу.

Що входить у налаштування preview environments?

Ми надаємо повний комплекс робіт під ключ:

  • Аудит поточної інфраструктури та CI/CD пайплайнів.
  • Проектування архітектури: вибір стратегії ізоляції БД, DNS-схема, політика TTL.
  • Реалізація Helm-чартів або Kustomize overlays для preview-оточень.
  • Налаштування GitHub Actions / GitLab CI workflow з автоматичним деплоєм та очищенням.
  • Інтеграція wildcard Ingress та TLS через cert-manager.
  • Тестування: одночасно відкриваємо 5 PR, перевіряємо ізоляцію даних та чистку.
  • Документація: runbook для чергового, опис додавання нових залежностей.
  • Навчання команди та підтримка після впровадження.

Порівняння стратегій ізоляції бази даних:

Стратегія Ізоляція Вартість Складність
Окрема схема PostgreSQL Середня Низька Низька
Ephemeral база (CloudNativePG) Висока Середня Середня
Зовнішній сервіс (Neon/PlanetScale) Висока Висока Низька

Орієнтири за термінами

Сценарій Термін
Статичний сайт / SPA (Vercel/Netlify) 0.5–1 день
Моноліт без бази, Docker Compose 1–2 дні
Сервіс з PostgreSQL, Kubernetes 3–5 днів
Мікросервіси, декілька залежностей 1–2 тижні

Вартість розраховується після аудиту: важливо зрозуміти поточний CI/CD стек та інфраструктуру. Окупається за рахунок прискорення розробки — час рев'ю скорочується з 2 днів до 4 годин.

Типові помилки та їх запобігання

Без автоматичного очищення через місяць накопичуються десятки мертвих namespace'ів, що збільшує хмарний рахунок. Рішення — налаштувати TTL або cleanup за подією закриття PR. Shared база без ізоляції призводить до конкуренції за міграції — допомагає schema-per-preview. Використання продакшен-секретів у preview-оточенні неприпустиме: потрібен окремий secrets store. Без ресурсних лімітів один активний PR може зайняти всю ноду; для preview достатньо 100m CPU та 256Mi memory. Ці заходи гарантують стабільність та економію.

Готові впровадити preview environments? Отримайте консультацію щодо вашого CI/CD — ми проаналізуємо поточну інфраструктуру і підберемо найкращу стратегію. Зв'яжіться з нами для аудиту та оцінки проекту.

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

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

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