Как я ускорил деплой контента в 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.

ссылка на оригинал статьи https://habr.com/ru/articles/1070252/