Skip to content

Деплой и эксплуатация

Прод отличается от dev не кодом, а дисциплиной вокруг него: порядок деплоя, наблюдаемость, бэкапы. Здесь — минимальный набор, который избавляет от «ночных» инцидентов.

Канонический порядок деплоя

Порядок важен: нарушение = битые запросы во время выката.

  1. composer install --no-dev --optimize-autoloader
  2. Сборка фронта (npm run build в контейнере — версии Node на хосте не совпадают)
  3. php artisan migrate --force
  4. php artisan optimize (config + route + view + event)
  5. php artisan storage:link (идемпотентно, но забывается на новых серверах)
  6. php artisan queue:restartобязательно: воркеры держат старый код в памяти
  7. Прогрев: запрос главной/ключевых страниц (заполняет opcache и кеши)

Для мажорных изменений схемы БД — php artisan down --render=... до, up после; для остального maintenance mode не нужен.

Миграции на проде — правила безопасности

  • migrate --force в деплое — да; migrate:fresh/migrate:refresh на проде — никогда (сносят данные).
  • Разрушающие изменения (drop/rename столбца) — в два релиза: сначала код перестаёт использовать, потом отдельной миграцией удаление. Откат кода не должен требовать отката схемы.
  • Большие таблицы — CONCURRENTLY-индексы и правила из спецификации миграций.
  • Перед рискованной миграцией — migrate --pretend (посмотреть SQL) и свежий бэкап.

Health-чеки и мониторинг

УровеньИнструментЧто даёт
Жив ли процесс/up (health route из коробки)Для Caddy/watchdog/докера
Живы ли зависимостиspatie/laravel-healthБД, Redis, диск, очередь, cron — одним endpoint'ом
Выполняется ли cronspatie/laravel-schedule-monitor«Молчаливо умерший» scheduler — частая скрытая авария
Не растёт ли очередьqueue:monitor в cronАлерт до того, как пользователи заметят
Ошибки в реальном времениSentry (free tier) / laravel-boost__last-errorСтектрейсы с контекстом, группировка
Метрики продаPulseМедленные запросы/джобы без внешней инфраструктуры
Доступность снаружиВнешний uptime-чекерИзнутри сервера свой сайт проверять нельзя (VPN-петля — правило студии)

Минимум для каждого прод-проекта студии: /up + schedule-monitor + внешний uptime + Telegram-канал алертов.

Бэкапы

  • spatie/laravel-backup: БД + файлы по расписанию, уведомление о сбое в Telegram — сбойнувший молча бэкап хуже отсутствующего.
  • Хранить минимум в двух местах (локально + S3-совместимое хранилище).
  • Бэкап без проверки восстановления — не бэкап. Раз в квартал: развернуть дамп в пустую БД, убедиться что приложение поднимается.
  • Перед ETL/массовыми операциями — внеплановый снапшот (правило из инцидентов студии).

Логи

  • Канал daily с ротацией (14 дней), уровень прода — warning/error; debug в проде = гигабайты шума.
  • Context::add() (request_id, user_id, order_id) — сквозной контекст во всех записях, инцидент разбирается за минуты вместо часов.
  • Логи контейнеров — с max-size (в студийном compose уже так), иначе диск кончится.
  • Смотреть: laravel-boost__read-log-entries / pail — не tail вслепую.

Очереди и cron в проде

  • Отдельные контейнеры queue и scheduler (по спецификации Docker), restart: unless-stopped.
  • Воркеры со --max-time=3600 — перезапуск по времени страхует от утечек памяти.
  • failed_jobs разбирать: алерт при росте, queue:retry после фикса причины.
  • Horizon — когда очередей/воркеров больше пары: балансировка и дашборд.

Секреты и конфигурация

  • .env вне git; .env.example — всегда актуален (новая переменная = сразу в example).
  • Ключи API — по окружениям: тестовые ключи платёжек в dev, боевые только в prod.
  • Ротация при увольнении/утечке: список «какие секреты где» держать в доке проекта.
  • APP_KEY — в менеджере паролей студии: без него шифрованные данные невосстановимы.

Обновления зависимостей

РитмДействие
Еженедельноcomposer outdated --direct — глазами; патчи ставить сразу
Ежемесячноcomposer update минорных + прогон тестов
Перед новым мажором LaravelRector + laravel-shift ускоряют; ждать 1–2 патч-релиза мажора
По CVEcomposer audit — в CI/чеклист; критичное — немедленно

Отставание на 2+ мажора превращает апгрейд в проект — дешевле обновляться ритмично.

Чеклист «проект уходит в прод впервые»

  • [ ] APP_DEBUG=false, APP_ENV=production, боевой APP_KEY сохранён
  • [ ] HTTPS + trustProxies (Caddy), редирект http→https
  • [ ] Кеш/сессии/очереди — Redis
  • [ ] /up + внешний uptime-мониторинг + Telegram-алерты
  • [ ] spatie/backup настроен, восстановление проверено
  • [ ] queue + scheduler контейнеры работают, schedule:list совпадает с ожиданиями
  • [ ] Sentry/лог-алерты подключены
  • [ ] robots.txt боевой (не Disallow всего сайта — частая забытая заглушка!)
  • [ ] Sitemap генерится, 301-карта старых URL работает
  • [ ] Тестовые данные/сидеры не попали в прод-БД
  • [ ] Права на storage/ и bootstrap/cache/
  • [ ] Деплой-скрипт повторяем одной командой (не «по памяти»)

Чеклист «инцидент на проде»

  1. laravel-boost__last-error / Sentry — что именно падает.
  2. php artisan about — окружение в порядке? кеши актуальны?
  3. Логи за период (read-log-entries), метрики Pulse.
  4. Очередь жива? queue:monitor, failed_jobs.
  5. Диск/память/БД: docker stats, состояние PostgreSQL.
  6. После фикса — post-mortem одним абзацем в доку проекта: причина, защита от повтора.

Внутренняя база знаний студии