We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

К списку статей

CI/CD pipeline для полиморфного стека — GitHub Actions + GitLab CI с Docker BuildKit

29 янв 2026 в 11:30 Усачёв Денис Евгеньевич

Современные проекты часто используют несколько технологий одновременно: микросервисы на PHP 8.3, веб‑приложения на Django 5 и быстрые API‑сервисы на FastAPI 0.115. Управлять таким полиморфным стеком в едином репозитории (монорепо) удобно, но требует продуманного CI/CD‑решения, способного автоматически тестировать, lint‑ить и собирать Docker‑образы для каждой части проекта.

Почему монорепо?

  • Единый процесс ревью и контроля качества кода.
  • Общие зависимости (например, базовый образ с OpenSSL, curl).
  • Упрощённое управление версиями и релизами.

Обзор архитектуры пайплайна

Мы комбинируем два инструмента:

  • GitHub Actions – отвечает за быстрые проверки при pull‑request (lint, юнит‑тесты).
  • GitLab CI – запускает тяжёлые задачи: сборку образов с Docker BuildKit, интеграционные тесты и деплой в продакшн.

Связующим звеном служит Docker BuildKit, который ускоряет построение многослойных образов и позволяет кэшировать промежуточные стадии между двумя CI‑системами.

Файловая структура монорепо

.
├─ .github
│   └─ workflows
│       └─ ci.yml                # GitHub Actions workflow
├─ .gitlab-ci.yml                # GitLab CI конфиг
├─ docker
│   ├─ base.Dockerfile           # Общий базовый образ
│   ├─ php
│   │   └─ Dockerfile            # PHP‑образ
│   ├─ django
│   │   └─ Dockerfile            # Django‑образ
│   └─ fastapi
│       └─ Dockerfile            # FastAPI‑образ
├─ services
│   ├─ php_app
│   │   ├─ src
│   │   └─ tests
│   ├─ django_app
│   │   ├─ src
│   │   └─ tests
│   └─ fastapi_app
│       ├─ src
│       └─ tests
└─ shared
    └─ utils.py                  # Общие скрипты

GitHub Actions: быстрый lint и юнит‑тесты

Workflow запускается на каждый PR и push в ветку main. Он использует отдельные jobs для каждой технологии, но общую стратегию кэширования зависимостей.

name: CI – Lint & Unit Tests
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  php:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up PHP 8.3
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: mbstring, intl, curl
      - name: Cache Composer dependencies
        uses: actions/cache@v3
        with:
          path: ~/.composer/cache
          key: composer-${{ hashFiles('services/php_app/composer.lock') }}
      - name: Install Composer deps
        run: composer install --working-dir=services/php_app --no-interaction --prefer-dist
      - name: PHP Lint (PHP_CodeSniffer)
        run: vendor/bin/phpcs -p services/php_app/src
      - name: Run PHPUnit
        run: vendor/bin/phpunit services/php_app/tests

  django:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python 3.12
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Cache pip packages
        uses: actions/cache@v3
        with:
          path: ~/.cache/pip
          key: pip-${{ hashFiles('services/django_app/requirements.txt') }}
      - name: Install requirements
        run: |
          python -m venv venv
          source venv/bin/activate
          pip install -r services/django_app/requirements.txt
      - name: Django lint (flake8)
        run: |
          source venv/bin/activate
          flake8 services/django_app/src
      - name: Run Django tests
        run: |
          source venv/bin/activate
          python manage.py test --settings=services.django_app.settings.test

  fastapi:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python 3.12
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Cache pip packages (FastAPI)
        uses: actions/cache@v3
        with:
          path: ~/.cache/pip
          key: pip-fastapi-${{ hashFiles('services/fastapi_app/requirements.txt') }}
      - name: Install FastAPI deps
        run: |
          python -m venv venv
          source venv/bin/activate
          pip install -r services/fastapi_app/requirements.txt
      - name: Lint with ruff
        run: |
          source venv/bin/activate
          ruff check services/fastapi_app/src
      - name: Run pytest
        run: |
          source venv/bin/activate
          pytest services/fastapi_app/tests

GitLab CI: сборка образов и деплой

GitLab CI отвечает за тяжёлые задачи: построение Docker‑образов с BuildKit, запуск интеграционных тестов в контейнерах и публикацию образов в GitLab Container Registry.

image: docker:23.0.5-dind

services:
  - docker:23.0.5-dind

variables:
  DOCKER_DRIVER: overlay2
  # Включаем BuildKit
  DOCKER_BUILDKIT: 1
  # Указываем кэш для BuildKit
  BUILDKIT_PROGRESS: plain

stages:
  - build
  - test
  - deploy

# Общий шаблон для сборки образа
.build_template: &build_template
  stage: build
  script:
    - echo "Building $IMAGE_NAME"
    - cd docker/$SERVICE
    - |
      docker build \
        --ssh default \
        --secret id=gitlab_token,src=$CI_JOB_TOKEN \
        -t $CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA \
        .
    - docker push $CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
  only:
    - main

# PHP образ
php_build:
  <<: build_template
  variables:
    SERVICE: php
    IMAGE_NAME: php-app

# Django образ
django_build:
  <<: build_template
  variables:
    SERVICE: django
    IMAGE_NAME: django-app

# FastAPI образ
fastapi_build:
  <<: build_template
  variables:
    SERVICE: fastapi
    IMAGE_NAME: fastapi-app

# Интеграционные тесты (пример для Django)

django_integration_test:
  stage: test
  script:
    - docker pull $CI_REGISTRY_IMAGE/django-app:$CI_COMMIT_SHORT_SHA
    - |
      docker run --rm \
        -e DATABASE_URL=$DATABASE_URL \
        $CI_REGISTRY_IMAGE/django-app:$CI_COMMIT_SHORT_SHA \
        python manage.py test --settings=services.django_app.settings.integration
  dependencies:
    - django_build

# Деплой в продакшн (пример с Kubernetes)

deploy_production:
  stage: deploy
  script:
    - echo "Deploying to Kubernetes"
    - kubectl set image deployment/php-deploy php=$CI_REGISTRY_IMAGE/php-app:$CI_COMMIT_SHORT_SHA --record
    - kubectl set image deployment/django-deploy django=$CI_REGISTRY_IMAGE/django-app:$CI_COMMIT_SHORT_SHA --record
    - kubectl set image deployment/fastapi-deploy fastapi=$CI_REGISTRY_IMAGE/fastapi-app:$CI_COMMIT_SHORT_SHA --record
  only:
    - tags

Docker BuildKit: ускоряем сборку

BuildKit позволяет:

  • Кешировать каждый слой независимо от CI‑провайдера.
  • Использовать --ssh и --secret для безопасного доступа к приватным репозиториям и токенам.
  • Параллельно выполнять шаги, например, установка зависимостей и копирование кода.

Пример базового Dockerfile, используемого всеми сервисами:

# docker/base.Dockerfile
FROM debian:bookworm-slim AS base
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates curl gnupg && \
    rm -rf /var/lib/apt/lists/

# Устанавливаем BuildKit secrets (пример)
# syntax=docker/dockerfile:1.4

Стратегии lint‑инга и тестирования

  • PHP 8.3: PHP_CodeSniffer (PSR‑12), PHPUnit для юнит‑тестов, PHPStan для статического анализа.
  • Django 5: flake8 + black, pytest‑django для тестов, django‑check‑migrations для проверки миграций.
  • FastAPI 0.115: ruff для lint, pytest + httpx для интеграционных тестов, pydantic‑validation в рантайме.

Управление секретами и переменными окружения

Оба CI‑сервиса поддерживают безопасное хранение секретов:

  • GitHub Actions – secrets (например, DOCKERHUB_USERNAME).
  • GitLab CI – CI_JOB_TOKEN, переменные уровня проекта и группы.

В Docker‑команде мы передаём их через --secret и --ssh, что гарантирует отсутствие их в финальном образе.

Мониторинг и обратная связь

После деплоя полезно включить:

  • Prometheus + Grafana для метрик контейнеров.
  • ELK‑стек (или Loki) для логов.
  • GitHub/GitLab статус‑чекеры в PR, показывающие результаты lint‑инга и тестов.

Заключение

Комбинация GitHub Actions и GitLab CI с включённым Docker BuildKit даёт гибкую, масштабируемую и быструю CI/CD‑систему для полиморфного стека в монорепозитории. Такой подход позволяет каждому сервису развиваться независимо, сохранять единый процесс контроля качества и быстро доставлять новые версии в продакшн.

Если вам нужен профессиональный аудит CI/CD, настройка пайплайнов под ваш стек или разработка микросервисов на PHP, Django и FastAPI – обратитесь в RybinskLab. Мы поможем построить надёжную инфраструктуру, автоматизировать релизы и обеспечить высокую скорость доставки ценности вашим пользователям.

* Материал подготовлен с использованием ИИ-ассистента, проверен и отредактирован экспертом RybinskLab.

Поделиться материалом:

Нужна сложная разработка?

Усачёв Денис Евгеньевич — проектирование архитектуры, бэкенд на PHP/Python, интеграции API и базы данных.

Обсудить проект