CI/CD для PHP с нуля: пошаговый гайд настройки пайплайна

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Зачем вам CI/CD, если вы не робот?

Представьте: пятница, вечер, вы только что допилили фичу, заливаете код на сервер через FTP (да, такое ещё бывает), и… сайт падает с белым экраном смерти. Знакомо? А если бы у вас был CI/CD pipeline для PHP, всё произошло бы автоматически: тесты отвалились бы ещё на этапе пуша, код не улетел бы на прод, а вы спокойно пошли бы пить чай.

Continuous Integration и Continuous Delivery (или Deployment) — это не просто модные аббревиатуры. Это ваш личный ассистент, который проверяет код, прогоняет тесты, линтит, собирает артефакты и деплоит на сервер. В этой статье я покажу, как настроить CI/CD pipeline для PHP с нуля, используя GitHub Actions. Без абстракций — только реальный код и рабочие примеры.

Что такое CI/CD pipeline и почему PHP-разработчику это нужно

CI/CD pipeline — это последовательность автоматических шагов, которые выполняются каждый раз, когда вы пушите код в репозиторий. Для PHP это особенно актуально, потому что:

  • PHP — динамический язык, и многие ошибки (опечатки, неверные типы) вылезают только в рантайме.
  • Деплой часто делают «на коленке» — через SCP, rsync или даже FTP (крик души).
  • Команды растут, и ручные проверки становятся узким горлышком.

Настроив CI/CD для PHP, вы получаете:

  • Автоматическое тестирование при каждом пуше.
  • Проверку стиля кода (PSR-12, ваш внутренний стандарт).
  • Автоматический деплой на staging/production.
  • Уведомления в Telegram/Slack о статусе сборки.

Выбираем инструмент: почему GitHub Actions?

Есть много вариантов: Jenkins, GitLab CI, Bitbucket Pipelines, CircleCI. Но для настройки CI/CD pipeline для PHP с нуля я рекомендую GitHub Actions. Почему?

  • Бесплатно для публичных репозиториев (и 2000 минут в месяц для приватных — хватает за глаза).
  • Всё в одном месте — код, issues, actions.
  • Огромная экосистема готовых действий (actions) — не нужно изобретать велосипед.

Но если вы используете GitLab — принципы те же, просто синтаксис YAML другой. Поехали.

Шаг 1: Структура репозитория и базовые файлы

Для демонстрации возьмём типичный PHP-проект на Laravel (но подход работает для любого фреймворка). Ваша структура должна выглядеть так:

my-php-app/
├── .github/
│   └── workflows/
│       └── ci-cd.yml
├── src/
├── tests/
├── composer.json
├── phpunit.xml
└── .php_cs.dist (если используете PHP-CS-Fixer)

Создайте папку .github/workflows/ и файл ci-cd.yml — это сердце вашего пайплайна.

Шаг 2: Базовый YAML — непрерывная интеграция (CI)

Начнём с простого: прогон тестов и линтинг при каждом пуше в main или pull request. Вот минимальный CI/CD pipeline для PHP:

name: PHP CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          extensions: mbstring, pdo, sqlite, gd
          coverage: xdebug

      - name: Install dependencies
        run: composer install --prefer-dist --no-progress

      - name: Run PHP CS Fixer (Lint)
        run: vendor/bin/php-cs-fixer fix --dry-run --diff

      - name: Run PHPStan (Static Analysis)
        run: vendor/bin/phpstan analyse src --level=5

      - name: Run Tests
        run: vendor/bin/phpunit --coverage-text

Что здесь происходит?

  • checkout — забираем код.
  • setup-php — устанавливаем нужную версию PHP и расширения.
  • composer install — ставим зависимости.
  • php-cs-fixer — проверяем код на соответствие стандартам (без исправления, только dry-run).
  • phpstan — статический анализ (ловит ошибки типов, неиспользуемые переменные).
  • phpunit — юнит-тесты с отчётом о покрытии.

Это классический CI/CD для PHP на минималках. После пуша GitHub сам запустит эти шаги. Если тесты упадут — в PR появится красная метка.

Шаг 3: Добавляем деплой (CD) — Continuous Delivery

Теперь самое интересное — автоматический деплой. Допустим, у вас есть сервер на Ubuntu с PHP и Nginx. Мы будем деплоить через SSH с помощью rsync (быстро и безопасно).

Сначала добавьте секреты в GitHub: Settings → Secrets and variables → Actions. Создайте:

  • SSH_PRIVATE_KEY — ваш приватный ключ (без пароля).
  • SSH_HOST — IP сервера.
  • SSH_USER — пользователь (обычно deploy или www-data).

Теперь дополните ваш ci-cd.yml новым job'ом:

deploy:
  needs: build-and-test
  runs-on: ubuntu-latest
  if: github.ref == 'refs/heads/main'  # только для main

  steps:
    - uses: actions/checkout@v4

    - name: Setup SSH
      run: |
        mkdir -p ~/.ssh
        echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
        chmod 600 ~/.ssh/id_rsa
        ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts

    - name: Deploy via rsync
      run: |
        rsync -avz --exclude '.git' --exclude 'vendor' --exclude 'tests' \
          --delete ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/var/www/my-app/

    - name: Run post-deploy commands
      run: |
        ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "
          cd /var/www/my-app &&
          php artisan migrate --force &&
          php artisan cache:clear &&
          php artisan config:cache
        "

Важно: needs: build-and-test гарантирует, что деплой запустится только после успешных тестов. Никакого «я задеплоил, а оно не работает».

Если вы используете Docker, вместо rsync можно собрать

Блоги

Рекомендаций по книгам