Как я ускорил деплой контента в Nuxt: с 12 минут до 21 секунды

Исправить слово или запятую в статье можно за несколько секунд. Но на моём сайте после такой правки запускался полный выпуск: установка зависимостей, сборка Nuxt и админки, генерация страниц, перезапуск приложения и итоговые проверки.

Последний успешный полный workflow перед запуском новой схемы шёл 12 минут 53 секунды. Для изменений в коде это нормально. Для исправленной запятой — слишком долго.

Я разделил два разных выпуска

Полный деплой остался для кода, конфигурации и смешанных изменений. Для статей я сделал отдельный путь, который принимает только Markdown блога и не пересобирает всё приложение.

Это не сокращённая версия обычного деплоя. Быстрый путь работает с отдельной проекцией контента, проверяет точный Git-коммит и переключает новую версию целиком. Если что-то идёт не так, сайт возвращается к предыдущему состоянию.

Как устроен быстрый путь

Я добавил три компонента:

Компонент

Что делает

Fast renderer

Готовит разрешённые страницы из выбранного Git-снимка

Gateway

Направляет обычные запросы в основное приложение, а разрешённые маршруты — в renderer

Активный указатель

Связывает публичные маршруты с точным Git-коммитом

Главная страница, список блога, сама статья и sitemap должны видеть один и тот же набор материалов. Простого копирования .md на сервер для этого недостаточно: основное приложение продолжит работать с данными и HTML из прежней сборки.

Поэтому renderer читает полный снимок блога из Git и создаёт новую проекцию. Gateway использует её только для маршрутов из строгого списка. Административные страницы, API, неизвестные URL и методы кроме GET и HEAD остаются на основном приложении.

Промпт: спроектировать быстрый путь для контента

Я хочу отделить публикацию Markdown-статей от полного деплоя Nuxt-сайта.

Сначала изучи текущий проект и установи:
- откуда build и runtime получают статьи;
- какие страницы, списки, API и sitemap зависят от блога;
- какие prerender-артефакты и кеши создаёт Nuxt;
- как сейчас устроены deploy, rollback и production-проверки.

После этого предложи минимальную архитектуру быстрого выпуска.
Она должна:
1. Принимать только полный 40-символьный Git SHA.
2. Разрешать только датированные Markdown-файлы блога.
3. Отклонять пустые, смешанные и неизвестные изменения.
4. Переключать полный неизменяемый снимок контента атомарно.
5. Сохранять согласованность статьи, списка блога, API и sitemap.
6. Возвращать предыдущий SHA и активный снимок при ошибке.

Ограничения:
- Не меняй код и production-инфраструктуру на этапе анализа.
- Не считай, что удаление prerender-файла автоматически включает SSR.
- Не ослабляй доступ к административным маршрутам и внутренним API.
- Не выдавай предполагаемую скорость за измеренный результат.

Формат ответа:
1. Текущий путь публикации.
2. Границы быстрого выпуска.
3. Предлагаемая архитектура.
4. Сценарии отказа и rollback.
5. План тестов и production-приёмки.
6. Открытые вопросы перед реализацией.

Как теперь публикуется статья

Быстрый выпуск получает полный 40-символьный SHA и выполняет несколько шагов:

  1. Проверяет, что коммит совпадает с вершиной origin/main.

  2. Подтверждает, что во всём наборе изменений есть только разрешённые Markdown-файлы.

  3. Формирует полную проекцию блога для выбранного SHA.

  4. Записывает её в неизменяемый файл.

  5. Атомарно переключает активный указатель.

  6. Открывает главную, блог, sitemap и изменённые статьи через HTTP.

Перед началом скрипт сохраняет исходный SHA и прежний активный указатель. Если синхронизация или HTTP-проверка завершается ошибкой, он возвращает оба значения назад. Читатель видит либо предыдущую целую версию сайта, либо новую.

Промпт: проверить выпуск перед подтверждением успеха

Проверь завершившийся content-only выпуск независимо от отчёта deploy-скрипта.

Входные данные:
- ожидаемый полный Git SHA: [SHA];
- список изменённых статей: [ФАЙЛЫ И URL];
- production host и публичный домен: [ЗНАЧЕНИЯ];
- имена основного приложения, renderer и gateway: [ИМЕНА].

Проверки:
1. Сверь ожидаемый SHA с `origin/main`, production HEAD
   и активным указателем контента.
2. Подтверди чистое состояние production checkout.
3. Открой изменённые статьи, главную, список блога, API и sitemap.
4. Для статьи проверь HTTP 200, заголовок, canonical, description,
   Open Graph и JSON-LD в полном HTML.
5. Сравни PID и счётчики перезапусков процессов до и после выпуска.
6. Убедись, что gateway отвечает через production-маршрут,
   а неизвестные и внутренние URL не перехвачены быстрым слоем.

Правила:
- Не считай статус workflow достаточным доказательством публикации.
- Не выводи секреты, environment и connection strings.
- Не исправляй production во время проверки.
- Если хотя бы одна обязательная проверка не прошла,
  не объявляй успех: покажи evidence и безопасный rollback.

Формат ответа:
1. Exact SHA и состояние Git.
2. Результаты HTTP-проверок.
3. Состояние процессов.
4. Проверка границ маршрутизации.
5. Итог: принят, отклонён или требуется rollback.

Где проходит граница

Быстрый путь разрешает добавлять, изменять и удалять только датированные файлы content/blog/*.md. Он проверяет весь diff от активной production-версии до запрошенного коммита.

Переименование, копирование, пустой diff, изменение кода или смешанный набор файлов отправляются в полный деплой. Если классификатор не может доказать, что перед ним только статьи, ускорения не будет.

Это ограничение важнее самой скорости. Без него отдельный путь постепенно превратился бы в запасной деплой для любых изменений.

Эта статья стала проверкой нового пути

Когда быстрый деплой был готов, его требовалось проверить настоящей публикацией. Я решил не создавать проходную тестовую заметку, а написать статью о самой работе. Тема того стоила: ожидаемый путь публикации сокращался с почти 13 минут до нескольких секунд.

Черновик родился в той же рабочей сессии с AI-агентом, где я вводил новую схему в production. В контексте ещё оставались исходная задача, неудачные проверки, откаты, команды и фактическая приёмка. Из этого журнала я собрал последовательный рассказ, а код и логи не позволили приписать системе то, чего она ещё не доказала.

Получился полезный цикл: рабочая сессия дала материал для статьи, а статья стала первым реальным тестом результата этой сессии.

Что показала первая публикация

Первый успешный выпуск этой статьи занял 21 секунду по времени GitHub Actions. Сам production-скрипт от начала проверки до завершения локальной приёмки отработал за 13,36 секунды.

Этап

Время

Проверка набора файлов

1,73 с

Git-проверка и переход

1,01 с

Синхронизация контента

2,91 с

HTTP-приёмка

7,67 с

Весь production-скрипт

13,36 с

Для сравнения я беру одинаковую внешнюю границу — длительность job в GitHub Actions. Полный workflow шёл 12 минут 53 секунды, быстрый — 21 секунду. В этой публикации выпуск ускорился в 36,8 раза.

Основной Nuxt-процесс, renderer и gateway не перезапускались: их PID и счётчики перезапусков до и после совпали. При этом сохранились проверка точного SHA, контроль набора файлов, согласованность маршрутов, HTTP-приёмка и автоматический откат.

Полный деплой никуда не исчез. Он по-прежнему обслуживает изменения в коде и остаётся точкой восстановления. Следующая полная сборка включает опубликованные статьи в обычный Nuxt-артефакт, после чего временная проекция больше не нужна.

Эта статья стала первой принятой проверкой быстрого пути. Два следующих обновления того же Markdown также прошли без полной сборки и перезапуска процессов. Быстрый выпуск теперь обслуживает обычные правки статей, а полный деплой остаётся для изменений в коде и включает актуальный контент в основной Nuxt-артефакт.

У вас публикация одной правки тоже запускает долгую сборку? Напишите или позвоните мне. Я посмотрю, где в проекте проходит граница между контентом и кодом, и помогу спроектировать быстрый путь так, чтобы он не обходил проверки и rollback.

Автор: rudin

Источник

Оставить комментарий