Пошаговое руководство по настройке Zero-Downtime CI/CD для Laravel
Почему классический git pull на продакшене — это мина замедленного действия
Многие начинающие разработчики деплоят код прямо на «живом» сервере: заходят по SSH, делают git pull, а затем накатывают миграции и обновляют зависимости через composer install. В этот момент проект гарантированно уходит в даунтайм. Пользователи ловят 500-е ошибки из-за несоответствия старых кэшированных файлов OPcache новому коду, а тяжелые миграции ломают текущие транзакции. Наша цель — изолировать сборку от продакшена с помощью GitLab Runner и сделать переключение версий моментальным.
Анатомия атомарного деплоя через символические ссылки
Суть Zero-Downtime (деплоя без простоя) сводится к тому, что на сервере создается структура папок, где текущая рабочая директория является лишь виртуальной ссылкой (symlink). Каждая новая сборка заливается в отдельную изолированную папку, и только после успешного финала веб-сервер перенаправляется на нее.
Шаг 1: Конфигурация рабочего процесса .gitlab-ci.yml
Создаем файл .gitlab-ci.yml в корне репозитория. Мы описываем глобальные стадии (stages) и подключаем легковесный Docker-образ с предустановленным PHP нужной версии для запуска тестов, а деплой осуществляем через SSH-клиент встроенного раннера.
Шаг 2: Алгоритм развертывания на сервере
Внутри изолированной SSH-сессии, которую инициировал GitLab Runner, мы выполняем строгую последовательность шагов, чтобы подготовить релиз к запуску:
- Создание новой папки в каталоге releases/ с уникальным ID (таймстампом).
- Клонирование репозитория в эту папку и установка production-зависимостей без dev-пакетов.
- Связывание общего файла конфигурации .env и папки storage/app/public из директории shared/.
- Запуск миграций базы данных в режиме принудительного выполнения (php artisan migrate --force).
- Создание новой символической ссылки и атомарная подмена старой.
Итоги и резюме
Итог автоматизации
Внедрение этой схемы полностью решает проблему «сломанного» продакшена. Если на этапе тестов или сборки Composer в GitLab CI/CD что-то пойдет не так, пайплайн аварийно остановится со статусом Failed, а сервер продолжит стабильно отдавать старый рабочий релиз из директории current. Время фактического переключения на новый код занимает менее 0.1 секунды.
Была ли полезна статья?
Оценки помогают мне понимать, какие темы вам наиболее интересны.