Режим обслуживания в Laravel: как сделать без падений и 502
Команда php artisan down выключает сайт целиком и роняет очередь деплоя, если сделать её наивно. Разбираем, как включить maintenance с secret-доступом, прогревом и без потери запросов на балансировщике.

Вы выкатываете миграцию, набираете php artisan down — и через минуту в мониторинге сыплются 503, служба поддержки получает жалобы, а вы сами не можете зайти проверить результат, потому что заглушку видите и вы тоже. Дальше выясняется, что балансировщик считает приложение упавшим и выкидывает ноды из ротации. Всё это лечится тремя-четырьмя флагами, которые есть в Laravel начиная с 8.x и работают в 10.x и 11.x. Разберём, как включать режим обслуживания так, чтобы он делал ровно то, что нужно, и ничего лишнего.
Что делает down на самом деле
Команда php artisan down не гасит PHP-процессы и не останавливает веб-сервер. Она создаёт файл-флаг в storage/framework/ (в старых версиях — storage/framework/down, в актуальных состояние хранится в кэше по драйверу, поэтому детали зависят от версии — смотрите документацию вашего релиза). Пока флаг на месте, middleware PreventRequestsDuringMaintenance перехватывает каждый HTTP-запрос и отдаёт заглушку с кодом 503.
Ключевой момент: проверка происходит на уровне фреймворка, то есть запрос уже прошёл веб-сервер, поднял PHP-FPM-воркер и загрузил ядро Laravel. Это не бесплатно. Если вам нужно снять нагрузку с приложения полностью — artisan down для этого не инструмент, гасить надо на уровне Nginx или балансировщика.
Режим обслуживания Laravel — это вежливая табличка «закрыто на переучёт», а не запертая дверь. Он показывает пользователю нужную страницу, но приложение под ним по-прежнему работает и потребляет ресурсы.
Термин: maintenance middleware
Промежуточный слой, который в Laravel запускается до вашего кода на каждый запрос и решает, пропустить его или вернуть 503. Именно он читает флаг обслуживания и держит логику исключений (secret, разрешённые пути). Найдёте его в App\Http\Middleware\PreventRequestsDuringMaintenance.
Как включить правильно
Наивный вызов без параметров — источник почти всех проблем. Собираем команду с флагами.
1. Доступ для себя через secret
Флаг --secret задаёт токен. Пройдя по /токен, вы получаете cookie-обход и видите живой сайт, пока остальные видят заглушку.
# Laravel 10.x / 11.x
php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
После этого открываете https://ваш-домен/1630542a-246b-4b66-afa1-dd72a4c43515 — редиректит на главную, ставит cookie, и приложение для вас работает как обычно. Токен генерируйте случайный (например, uuid), не используйте угадываемые слова: любой, кто знает секрет, обходит обслуживание.
2. Своя страница-заглушка вместо стандартной
Флаг --render заранее рендерит Blade-шаблон и кладёт готовый HTML. Это важно: если во время обслуживания вы ломаете зависимости композером, стандартная заглушка может не отрендериться и пользователь получит белый экран с ошибкой. Предрендеренный HTML отдаётся без запуска приложения.
php artisan down --render="errors::503"
Здесь errors::503 — путь к вашему Blade-шаблону resources/views/errors/503.blade.php. Проверьте, что файл существует до вызова команды.
3. Правильный HTTP-статус и Retry-After
По умолчанию отдаётся 503 — и это верно для поисковиков: Google понимает 503 как «временно, зайду позже», не выкидывает страницы из индекса. Флаг --retry добавляет заголовок Retry-After в секундах.
php artisan down --retry=60
Если вместо 503 отдать 200 с текстом «идут работы» — поисковик проиндексирует заглушку вместо контента. Не делайте так.
4. Разрешённые пути
Флаг --redirect отправляет всех на указанный URL. А если нужно оставить рабочими вебхуки платёжной системы или health-check балансировщика — их пути надо исключить из middleware вручную, в свойстве $except:
<?php
// app/Http/Middleware/PreventRequestsDuringMaintenance.php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
class PreventRequestsDuringMaintenance extends Middleware
{
// Эти пути продолжат работать во время обслуживания
protected $except = [
'health', // проверка живости для балансировщика
'webhooks/payment', // вебхук платёжного провайдера
];
}
В Laravel 11.x структура middleware изменилась — конфигурация переехала в bootstrap/app.php. Если у вас 11.x, исключения задаются через $middleware->preventRequestsDuringMaintenance(except: [...]) в bootstrap-файле. Точный синтаксис для вашей версии сверьте с документацией по маршрутизации и middleware.
Собираем боевую команду
На проде обычно нужны все флаги сразу:
php artisan down \
--secret="$(php -r 'echo bin2hex(random_bytes(16));')" \
--render="errors::503" \
--retry=60
Секрет здесь генерируется на лету — но тогда вы не узнаете значение. На практике генерируйте токен заранее, выводите в лог деплоя или в переменную окружения, чтобы потом было чем зайти.
Флаги коротко
| Флаг | Что делает | Зачем на проде |
|---|---|---|
--secret | Токен обхода заглушки | Проверить деплой, пока сайт закрыт для всех |
--render | Предрендер заглушки в статический HTML | Заглушка не сломается, если сломан composer |
--retry | Заголовок Retry-After в секундах | Сигнал поисковикам и клиентам о повторе |
--redirect | Редирект всех запросов на URL | Увести на статичную страницу-заглушку |
$except | Пути в обход обслуживания | Вебхуки и health-check продолжают работать |
Где это ломается
Три ситуации, в которых наивное включение бьёт по проду.
- Балансировщик выкидывает ноды. Если health-check ходит на обычный маршрут и получает 503, балансировщик считает инстанс мёртвым и убирает его из ротации. Итог — вы включили обслуживание на всех нодах и потеряли даже возможность показать заглушку. Health-check должен идти на путь из
$except. - Очереди продолжают работать.
artisan downкасается только HTTP. Воркеры очередей (queue:work) продолжают выполнять джобы, обращаться к БД, которую вы, возможно, как раз мигрируете. Перед миграцией останавливайте воркеры отдельно:php artisan queue:pauseв свежих версиях или через супервизор. - Кэш-драйвер состояния. В актуальных версиях состояние обслуживания может храниться в кэше. Если вы во время деплоя чистите кэш (
cache:clear), можно случайно снять флаг обслуживания. Проверяйте порядок команд в деплой-скрипте.
Атомарный деплой и maintenance
Если вы деплоите через симлинк-релизы (Envoyer, Deployer, ручной атомарный деплой), режим обслуживания часто вообще не нужен: новый релиз собирается в отдельной папке, а переключение симлинка мгновенно. artisan down оправдан, когда деплой не атомарный или когда миграция БД несовместима со старым кодом — тогда закрываете сайт на время миграции.
Выключение
php artisan up
Команда удаляет флаг, приложение возвращается к работе. Проверьте после этого: заголовок ответа на любой странице должен быть 200, а не 503. Быстрая проверка из консоли:
curl -I https://ваш-домен/ | head -n 1
Должно вернуться HTTP/2 200. Если всё ещё 503 — флаг не снялся, повторите up и проверьте кэш-драйвер.
Что настроить дальше
Оберните включение и выключение в деплой-скрипт с фиксированным порядком: пауза очередей → down с секретом → миграции → сборка ассетов → up → возобновление очередей. Заведите заранее подготовленный resources/views/errors/503.blade.php с фирменным оформлением и без внешних зависимостей на CDN — заглушка должна открываться, даже когда приложение частично сломано. И вынесите health-check на отдельный лёгкий маршрут, который не трогает БД: тогда балансировщик переживёт любое обслуживание. Настройка очередей под деплой — отдельная тема, здесь мы разобрали только HTTP-режим обслуживания.
IT-архитектор / SQL-оптимизатор: Поиск N+1, оптимизация запросов, code review, поиск багов.
Спросить за 20 ₽Источники: Laravel — Configuration: Maintenance Mode (официальная документация), Laravel — Deployment (официальная документация)
Частые вопросы
У меня Laravel 11.x, а пример с $except в классе middleware — сработает?
Я включил down и теперь сам не могу зайти проверить сайт — что делать?
Поисковики выкинут сайт из индекса, пока идёт обслуживание?
Останавливает ли down очереди и cron?
Заглушка показывает белый экран или ошибку — почему?
Нужен ли вообще режим обслуживания при атомарном деплое?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.