Как я ускорил деплой контента в 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 и выполняет несколько шагов:
-
Проверяет, что коммит совпадает с вершиной
origin/main. -
Подтверждает, что во всём наборе изменений есть только разрешённые Markdown-файлы.
-
Формирует полную проекцию блога для выбранного SHA.
-
Записывает её в неизменяемый файл.
-
Атомарно переключает активный указатель.
-
Открывает главную, блог, 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

