Плановые работы — рутина. Но «выключить сайт» можно по‑разному: кто-то склеивает редиректом на страницу-заглушку с кодом 200, кто-то просто роняет приложение и ловит 502. Оба варианта вредят пользователям и SEO. Правильный путь — вернуть понятный ответ 503 Service Unavailable, приложить разумный Retry-After, показать легкую статическую страницу, не уезжающую в кэш, и при необходимости пропустить администратора или мониторинг мимо maintenance-режима.
HTTP-семантика: почему именно 503
503 Service Unavailable — единственный статус, который официально говорит: «Ресурс недоступен временно». Его понимают браузеры, кроулеры и прокси. С 503 вы можете сообщить, когда вернуться, через Retry-After — это секундами (например, 3600) или точной датой в GMT (например, Fri, 07 Nov 2025 12:00:00 GMT).
- 302/307 на «заглушку» с 200 ломают семантику и могут индексироваться как отдельная страница.
- 500/502/504 сигналят про аварию, а не плановые работы; поисковики могут трактовать это хуже.
- 404/410 — точно не для обслуживания: это «нет ресурса».
Если вы отдаете 503 недолго (часы) и ставите
Retry-After, поисковые роботы обычно снижают темп обхода, не выбрасывая страницы из индекса.
SEO и роботы: нюансы поведения
Ключевое: возвращайте 503 на тех же URL, где обычно 200. Не переселяйте пользователей на отдельный домен/путь с кодом 200. Исключения — штучные и осознанные. Например, доступ к /robots.txt часто стоит оставить рабочим (200), чтобы робот читал актуальные правила и не «залипал» на retry.
Практика показывает: при простоях до нескольких часов индексация не страдает. Если работы затягиваются на дни, кроулеры начнут сильнее снижать активность; часть несущественных страниц может временно выбыть из выдачи. Поэтому лучше фокусироваться на сокращении окна обслуживания, чем на попытках «обмануть» кроулеров редиректами.

Кэш и прокси: не давайте кэшировать 503
Типичная ошибка — 503 с дефолтными заголовками, который уезжает в CDN/прокси и продолжает жить после завершения работ. Ставьте строгие анти‑кэш заголовки на все ответы maintenance-страницы:
Cache-Control: no-store, no-cache, must-revalidate, max-age=0Pragma: no-cache(для старых клиентов)Retry-After(чтобы роботы и клиенты понимали, когда вернуться)
Подробно про смежные заголовки смотрите в материале HTTP Security Headers для Nginx и Apache.
Nginx: простой и расширенный шаблон maintenance
Минимальный вариант: флаг-файл и статическая страница
Файл-флажок включает режим. Ошибки приложения (500/502/504) можно тоже переводить в 503, чтобы посетитель видел единый сценарий.
server {
server_name example.com;
root /var/www/site/public;
# Базовый роутинг приложения
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Включаем maintenance при наличии флага
if (-f /var/www/site/maintenance.flag) {
return 503;
}
# Подменяем 5xx на 503 (опционально)
error_page 500 502 504 =503 /maintenance.html;
error_page 503 /maintenance.html;
# Статика maintenance с нужными заголовками
location = /maintenance.html {
internal;
add_header Retry-After 3600 always;
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always;
add_header Pragma no-cache always;
}
# PHP (если используется)
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_intercept_errors on;
}
}
Здесь maintenance.html ищется в root (каталоге сайта). Директива internal запрещает прямой запрос этого файла извне — он доступен только через error_page.
Исключения: разрешить роботов, health-check и белый список IP
Часто нужно пропустить мониторинг или оставить рабочим /robots.txt. Проще всего включать 503 только внутри основного location / — так исключения обрабатываются через отдельные локации.
server {
server_name example.com;
root /var/www/site/public;
# robots.txt работает даже при maintenance
location = /robots.txt { try_files /robots.txt =404; }
# health-check (например, /status) тоже можно оставить 200
location = /status { return 200; }
# Белый список IP (админ/мониторинг)
set $bypass_maint 0;
if ($remote_addr = 203.0.113.10) { set $bypass_maint 1; }
if ($remote_addr = 203.0.113.11) { set $bypass_maint 1; }
# Основной роутинг + maintenance
location / {
if ($bypass_maint = 0) {
if (-f /var/www/site/maintenance.flag) { return 503; }
}
try_files $uri $uri/ /index.php?$query_string;
}
error_page 500 502 504 =503 /maintenance.html;
error_page 503 /maintenance.html;
location = /maintenance.html {
internal;
add_header Retry-After 3600 always;
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always;
add_header Pragma no-cache always;
}
}
Такой подход предсказуем: отдельные пути обслуживаются как обычно, а все остальное — через 503 при наличии флага. Если регулярно ловите 502/504 из PHP-FPM, пригодится разбор причин и таймаутов в статье Gateway timeout между Nginx и PHP-FPM.
На VDS у вас полный контроль над Nginx/Apache и удобнее выносить шаблоны в общие include. На виртуальном хостинге чаще доступен только .htaccess — ниже готовый вариант.
Apache: .htaccess и vhost-конфигурация
.htaccess (часто доступно на shared‑хостинге)
Используем mod_rewrite и mod_headers. Флаг-файл включает 503, при этом исключаем /robots.txt, /status и белый список IP. Заголовки отправляем только когда срабатывает правило maintenance (через переменную окружения).
RewriteEngine On
# Включаем maintenance по переменной или флаг-файлу
RewriteCond %{ENV:MAINTENANCE} =1 [OR]
RewriteCond /home/user/site/maintenance.flag -f
# Исключения: IP и пути
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.10$
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.11$
RewriteCond %{REQUEST_URI} !^/robots\.txt$
RewriteCond %{REQUEST_URI} !^/status$
# Отдаем 503 и помечаем env для заголовков
RewriteRule ^ - [R=503,L,E=MAINT:1]
# Кастомная страница обслуживания
ErrorDocument 503 /maintenance.html
# Заголовки только для maintenance-ответов
Header always set Retry-After "3600" env=MAINT
Header always set Cache-Control "no-store, no-cache, must-revalidate, max-age=0" env=MAINT
Header always set Pragma "no-cache" env=MAINT
maintenance.html должен быть статическим и легким. Мы исключили его из переписывания, чтобы не попасть в цикл редиректов/503. Если Header в .htaccess недоступен, переносите строки заголовков в конфигурацию виртуального хоста.
Виртуальный хост: точно так же, но «чище»
Логику можно повторить на уровне vhost, используя RewriteCond и ErrorDocument там же. Плюс — проще централизованно задать заголовки и исключения для нескольких сайтов.
Retry‑After: секунды или дата?
Retry-After принимает два формата:
- Число секунд:
Retry-After: 1800— вернитесь через 30 минут. - Дата/время в формате RFC 7231:
Retry-After: Fri, 07 Nov 2025 12:00:00 GMT.
Для кратких работ удобнее секунды — проще поменять на лету. Для заранее объявленных окон — дата/время. Не ставьте гигантские значения: это не «защита от роботов», а подсказка, и поисковые системы все равно адаптируют частоту по своему усмотрению.
Кастомная страница: что на ней должно быть
Поддерживайте три принципа: лаконичность, малый вес, отсутствие тяжелых внешних зависимостей. Никаких больших JS-бандлов; чистый HTML+минимум CSS (инлайн, если он нужен). Текст — коротко о работах и ориентировочном времени завершения; контактный канал для клиентов.
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Сайт временно недоступен (обслуживание)</title>
<meta name="robots" content="noindex, nofollow">
</head>
<body>
<h1>Обслуживание</h1>
<p>Мы проводим плановые работы и скоро вернемся в онлайн.</p>
<p>Пожалуйста, попробуйте позже.</p>
</body>
</html>
Метатег robots здесь избыточен при 503, но не повредит, если по ошибке эту страницу отдадут с 200.
Тесты: что проверить перед и после включения
Мини-чеклист:
- 503 на основных URL: статус, заголовки
Retry-Afterи анти‑кэш. - Исключения (IP/пути) реально работают и не «тонут» в общих правилах.
- Файл
maintenance.htmlобслуживается быстро, без внешних блокирующих ресурсов. - Ошибки приложения (500/502/504) подменяются на 503 (если решили так настраивать).
- После снятия флага все снова отдает 200, а 503 больше не появляется.
# Проверить статус и заголовки
curl -I https://example.com/
# Проверить исключение для robots.txt
curl -I https://example.com/robots.txt
# Проверить, что 500/502/504 мапятся в 503 (опционально)
# Смоделируйте временно ошибку бэкенда; затем curl -I нужный URL

Автоматизация и операционный процесс
Простой и безопасный способ — использовать «флаг-файл» и скрипт-обертку:
- Загрузите статическую
maintenance.htmlрядом сrootсайта. - Перед началом работ создайте
maintenance.flagи убедитесь, что 503 включился. - Выполните миграции/обновления.
- Удалите флаг и проверьте, что 200 вернулся.
# включить maintenance
ssh user@host "touch /var/www/site/maintenance.flag"
# выключить maintenance
ssh user@host "rm -f /var/www/site/maintenance.flag"
В Nginx и Apache проверка наличия файла происходит на каждом запросе — перезагрузка сервера не требуется. Это делает переключение мгновенным и атомарным.
Частые ошибки и как их избежать
- Редирект на страницу 200. Нельзя. Возвращайте 503 на месте.
- Отсутствует Retry‑After. Добавьте: роботам и клиентам так проще.
- Кэширует CDN/прокси. Ставьте
Cache-Control: no-storeи аналогичные заголовки; при необходимости правила обхода кеша для 5xx. - Долгий maintenance. Планируйте работы так, чтобы укладываться в часы, а не дни. Для крупных релизов продумайте стратегию без простоя (blue/green, канареечные выкладки).
- Забыли исключить robots.txt или здоровье. Продумайте исключения заранее; но не маскируйте мониторинг, если он должен сигналить о простое.
- Тяжелая maintenance‑страница. Без JS-фреймворков и внешних зависимостей; только минимальный HTML.
API и фоновые клиенты
Для API 503 тоже корректен: клиенты могут ретраить с экспоненциальной паузой и учитывать Retry-After. Если maintenance затрагивает не весь API, отделите эндпоинты, которые можно оставить доступными, и документируйте возможные статусы, чтобы не удивлять потребителей.
Итого
Правильный maintenance — это не просто «выдать заглушку», а сохранить корректную HTTP‑семантику, не сломать кэш и кроулинг. 503 + Retry-After + компактная статическая страница и пара исключений решают задачу без сюрпризов. Используйте флаг‑файл и шаблоны выше — и плановые работы перестанут быть стрессом для пользователей, поисковиков и команды.


