> Как устроен процесс деплоя и инфраструктура (PHP)

Уровень: senior · Роль: backend · Язык: PHP · Категория: Технические вопросы

Компании: Travelata

Стек: PHP

> Пример ответа

Короткий ответ

Деплой PHP-приложения - это автоматизированный процесс доставки кода из репозитория на серверы, включающий сборку артефактов, миграции БД, обновление зависимостей и перезапуск сервисов. Инфраструктура для senior-уровня обычно состоит из нескольких сред (dev/staging/prod), CI/CD пайплайна (GitLab CI, GitHub Actions), балансировщика нагрузки, нескольких PHP-FPM воркеров и общего хранилища для сессий и кеша. Ключевой момент - zero-downtime деплой через rolling update или blue-green стратегию.

Подробное объяснение

Процесс деплоя в PHP-проекте включает несколько обязательных этапов:

  1. Сборка: composer install --no-dev, генерация автозагрузчика, сборка фронтенда (если есть), создание артефакта (архива или docker-образа).
  2. Миграции БД: выполняются отдельным шагом, часто с блокировкой деплоя до их завершения. Для больших таблиц используются expand-contract миграции.
  3. Обновление файлов: атомарная замена кода через symlink на release-директорию или через docker-образы с immutable тегами.
  4. Прогрев кеша: opcache reset, config cache, route cache, view cache.
  5. Перезапуск сервисов: php-fpm reload, supervisor restart для воркеров очередей, systemd units.

Инфраструктура для PHP-приложения уровня senior:

  • Веб-сервер: nginx как reverse proxy, отдаёт статику, проксирует динамику на php-fpm.
  • PHP-FPM: пул воркеров с настройками pm.max_children, pm.start_servers, pm.max_requests.
  • Балансировка: nginx upstream или cloud load balancer (ALB, HAProxy) с health check на /healthz.
  • Хранилище: общий Redis для сессий и кеша, S3-совместимое хранилище для файлов (важно при нескольких воркерах).
  • Очереди: RabbitMQ или Redis для async-задач, supervisor для воркеров.
  • Мониторинг: Prometheus + Grafana, логи в ELK или Loki.

Стратегии деплоя:

  • Rolling update: по одному серверу из пула, nginx отключает сервер из upstream, обновляет, включает обратно.
  • Blue-green: два полных окружения, переключение трафика через роутер.
  • Canary: постепенное переключение процента трафика на новую версию.

Для PHP важно учитывать opcache: при деплое через symlink нужно вызывать opcache_reset() или настроить opcache.validate_timestamps=0 и сбрасывать вручную.

На практике

Типичный пайплайн для PHP-проекта на GitLab CI:

  1. Статический анализ: phpstan, phpcs, psalm.
  2. Тесты: phpunit, integration tests с тестовой БД.
  3. Сборка: composer install --no-dev --optimize-autoloader, сборка фронта.
  4. Деплой на staging: автоматически после merge в develop.
  5. Деплой на prod: по тегу или вручную через approval.

Для zero-downtime деплоя на выделенных серверах используется подход с release-директориями:

/var/www/app/
  releases/
    20250101_120000/
    20250102_090000/
  current -> releases/20250102_090000
  shared/ (env, storage, logs)

Деплойный скрипт: rsync нового релиза, composer install, миграции, symlink переключение, php-fpm reload.

Для docker-подхода: сборка образа с тегом commit sha, push в registry, rolling update через docker-compose или kubernetes.

Миграции БД - отдельный шаг. Для больших таблиц нельзя делать ALTER TABLE с блокировкой. Используется gh-ost или pt-online-schema-change, либо expand-contract: добавить колонку, деплой кода, бэкфилл данных, удалить старую колонку.

Пример кода

Деплойный скрипт на bash для zero-downtime деплоя:

BASH
#!/bin/bash
set -e
APP_DIR="/var/www/app"
RELEASE_DIR="$APP_DIR/releases/$(date +%Y%m%d_%H%M%S)"
SHARED_DIR="$APP_DIR/shared"
mkdir -p "$RELEASE_DIR"
rsync -a --exclude-from="$APP_DIR/.rsyncignore" ./ "$RELEASE_DIR/"
ln -sfn "$SHARED_DIR/.env" "$RELEASE_DIR/.env"
ln -sfn "$SHARED_DIR/storage" "$RELEASE_DIR/storage"
cd "$RELEASE_DIR"
composer install --no-dev --optimize-autoloader --no-interaction
# Миграции БД
php artisan migrate --force
# Прогрев кеша
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Переключение symlink
ln -sfn "$RELEASE_DIR" "$APP_DIR/current"
# Сброс opcache
php -r "opcache_reset();"
# Reload php-fpm
sudo systemctl reload php8.2-fpm
# Очистка старых релизов (оставить последние 5)
cd "$APP_DIR/releases" && ls -t | tail -n +6 | xargs -r rm -rf

Конфиг nginx для health check:

upstream php_backend {
    server 10.0.0.1:9000;
    server 10.0.0.2:9000;
}

server {
    listen 80;
    server_name app.example.com;

    location /healthz {
        access_log off;
        return 200 "ok";
    }

    location / {
        try_files $uri @php;
    }

    location @php {
        fastcgi_pass php_backend;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /var/www/app/current/public/index.php;
    }
}

Как отвечать на собеседовании

Начни с общей схемы: репозиторий → CI → артефакт → серверы → переключение трафика. Затем уточни, что для PHP критичны opcache и миграции БД. Опиши конкретную стратегию деплоя, которую использовал: как устроены release-директории или docker-образы, как решается проблема с сессиями и файлами при нескольких серверах.

Упомяни, что деплой - это не только заливка файлов, а цепочка: статический анализ, тесты, сборка, миграции, прогрев кеша, перезапуск. Покажи понимание trade-off между скоростью деплоя и безопасностью: canary требует больше инфраструктуры, но снижает риск.

Если спросят про откат - объясни, что при symlink-подходе откат это переключение symlink на предыдущий релиз, при docker - переключение тега образа. Миграции откатывать сложнее, поэтому они должны быть обратно совместимыми.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание полного цикла деплоя, а не только команды git pull.
  • Знание проблем PHP-специфики: opcache, php-fpm reload, composer autoload.
  • Умение проектировать инфраструктуру: как обеспечить zero-downtime, как хранить файлы и сессии при нескольких серверах.
  • Понимание работы с БД при деплое: миграции, блокировки, expand-contract.
  • Навыки автоматизации: CI/CD пайплайны, скрипты деплоя, обработка ошибок.
  • Умение рассуждать о стратегиях: когда нужен blue-green, когда достаточно rolling.

Типичные ошибки

  • Утверждение, что деплой - это просто git pull на сервере. Это не работает для продакшена с несколькими серверами.
  • Игнорирование opcache: после деплоя код остаётся старым в памяти php-fpm.
  • Миграции БД выполняются после переключения кода - это ломает обратную совместимость.
  • Нет отката: если деплой сломался, нет плана возврата на предыдущую версию.
  • Файлы хранятся локально на сервере - при нескольких воркерах пользователь получает разные данные.
  • Нет health check: балансировщик продолжает слать трафик на сломанный сервер.
  • Деплой на прод без staging: баги обнаруживаются на пользователях.
  • Не учитывается, что composer install на проде может упасть из-за отсутствия dev-зависимостей или network issues - нужен lock-файл и кеш пакетов.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью