Перейти к содержимому

Build Output Manifest

Build Output Manifest — JSON-файл .onreza/manifest.json, который описывает что нужно развернуть и где это должно работать. Это контракт между вашим проектом и платформой.

Платформа читает манифест и выполняет ровно то, что в нём написано:

  • Статические файлы → CDN (мгновенная отдача, кэширование)
  • Fetch-handlers → Edge Runtime (V8 isolate, быстрый cold start)
  • Серверные процессы → Compute sandbox (полный Node.js/Bun)

Ничего делать не нужно. nrz deploy автоматически создаёт манифест для статических сайтов.

nrz deploy определяет тип фреймворка и генерирует манифест автоматически. Никаких дополнительных пакетов устанавливать не нужно.

nrz deploy создаёт два слоя: статические ассеты → CDN, серверный процесс → Compute.

Создайте .onreza/manifest.json в output-директории вашего билда:

{
"version": 1,
"layers": [
{ "name": "site", "target": "STATIC", "directory": "." }
],
"routes": [
{ "pattern": "^/.*$", "layer": "site" }
]
}

Слой — это набор файлов с указанием, где их запускать:

TargetЧто этоКогда использовать
STATICCDN-раздача файловHTML, CSS, JS, изображения, шрифты
ISOLATEV8 Runtime (edge)SSR, API endpoints, ISR — лёгкий, быстрый cold start
COMPUTEПолный серверный процессNext.js standalone, Express, Fastify — полный Node.js/Bun

Один деплой может содержать несколько слоёв. Статика раздаётся через CDN бесплатно и мгновенно, а compute-ресурсы тратятся только на динамические запросы.

Маршруты определяют, какой слой отвечает на какой URL:

{
"routes": [
{ "pattern": "^/_next/static/.*$", "layer": "static", "priority": 100 },
{ "pattern": "^/api/.*$", "layer": "server", "priority": 20 },
{ "pattern": "^/.*$", "layer": "server", "priority": 0 }
]
}

Как работает:

  1. Маршруты сортируются по priority (больше = проверяется раньше)
  2. Первый regex-match побеждает
  3. Запрос отправляется в слой, указанный в layer
Тип маршрутаPriority
Hashed assets (/_next/static/)100
Конкретные статические страницы50
ISR страницы30
API routes20
Catch-all (серверный fallback)0

Поле priority опционально (default: 0), но рекомендуется указывать явно при наличии нескольких маршрутов.

{
"version": 1,
"layers": [
{ "name": "site", "target": "STATIC", "directory": "dist" }
],
"routes": [
{ "pattern": "^/.*$", "layer": "site", "priority": 0 }
]
}
ПолеТипОбязательноОписание
namestringдаУникальное имя слоя (до 64 символов)
target"STATIC"даТип слоя
directorystringдаДиректория с файлами относительно output-директории
ПолеТипОбязательноОписание
namestringдаУникальное имя слоя
target"ISOLATE"даТип слоя
directorystringдаДиректория с файлами бандла
entrystringдаПуть к entry файлу внутри directory
exportstringнетЭкспортируемый символ (default: "default")
runtimeobjectнетНастройки ресурсов
ПолеТипОбязательноОписание
namestringдаУникальное имя слоя
target"COMPUTE"даТип слоя
directorystringдаДиректория с серверным процессом
entrystringдаПуть к entry файлу
runtimeobjectнетНастройки ресурсов
ПолеТипОбязательноОписание
patternstringдаRegex-паттерн для URL (Rust regex синтаксис)
layerstringдаИмя слоя из layers
prioritynumberнетПриоритет (default: 0, больше = раньше)
methodsstring[]нетHTTP методы: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
revalidatenumberнетВремя кэша в секундах (ISR). Только для ISOLATE/COMPUTE слоёв
fallthroughbooleanнетПри 404 перейти к следующему маршруту. Default: true для STATIC, false для остальных

Когда STATIC-маршрут с fallthrough: true (default для всех STATIC) не находит файл в хранилище, запрос переходит к следующему подходящему маршруту вместо 404.

{
"routes": [
{ "pattern": "^/.*\\..*$", "layer": "static", "priority": 50 },
{ "pattern": "^/.*$", "layer": "server", "priority": 0 }
]
}
  • GET /favicon.ico → паттерн ^/.*\\..*$ совпал → STATIC (файл есть) → CDN
  • GET /style.css → паттерн ^/.*\\..*$ совпал → STATIC (файл есть) → CDN
  • GET /unknown.js → паттерн ^/.*\\..*$ совпал → STATIC (файла нет, fallthrough) → ^/.*$ → server → SSR
  • GET /about → паттерн ^/.*\\..*$ не совпал (нет расширения) → ^/.*$ → server → SSR напрямую
ISOLATECOMPUTE
RuntimeV8 isolateПолный Bun / Node.js
Cold start~5ms (warm)~500ms–2s
Handlerfetch(Request): ResponseПроизвольный HTTP сервер
Файловая системаНетRead-only (кроме /tmp)
WebSocketНетДа
Native modulesНетДа
Подходит дляAstro SSR, SvelteKit, API handlersNext.js standalone, Express, Fastify

Правило: если ваш фреймворк умеет экспортировать fetch handler — используйте ISOLATE. Если нужен полный серверный процесс — COMPUTE.

Для ISOLATE и COMPUTE слоёв можно задать лимиты ресурсов в поле runtime:

{
"name": "server",
"target": "COMPUTE",
"directory": "standalone",
"entry": "server.js",
"runtime": {
"timeoutMs": 60000,
"memoryMb": 512
}
}
ПараметрISOLATE defaultCOMPUTE defaultОписание
timeoutMs30 000 (30s)300 000 (5 мин)Таймаут выполнения
memoryMb128256Лимит памяти
maxConcurrency10Макс. параллельных выполнений (только ISOLATE)

Middleware — перехватчики запросов, которые выполняются до маршрутизации:

{
"middleware": [
{
"name": "auth",
"bundlePath": "middleware/auth.mjs",
"codeHash": "sha256-abc123",
"matchers": ["^/(?:api|dashboard)/.*$"],
"priority": 10
}
]
}
ПолеОписание
nameУникальное имя
bundlePathПуть к файлу middleware
codeHashSHA-256 хэш файла
matchersСписок regex-паттернов для URL (Rust regex синтаксис)
priorityПорядок выполнения (выше = раньше, default: 0)

Подробнее о Middleware

Необязательные метаданные для dashboard и отладки:

{
"meta": {
"framework": { "name": "astro", "version": "5.2.0" }
}
}

Платформа показывает их в dashboard: «Deployed with Astro 5.2.0». Можно добавить любые поля — платформа сохраняет, но не валидирует содержимое. Максимальный размер: 16 KB.

Если манифест невалиден, деплой отклоняется с понятным сообщением:

Manifest validation failed:
layers[1].entry: Entry not found: "server/entry.mjs"
routes[2].layer: Route references unknown layer: "cdn"
See: docs.onreza.ru/manifest

Паттерны маршрутов и matchers middleware используют синтаксис Rust regex crate. Следующие JavaScript-специфичные фичи не поддерживаются и вызовут ошибку валидации:

  • Lookahead / lookbehind: (?=...), (?!...), (?<=...), (?<!...)
  • Backreferences: \1, \2 и т.д.
  • Atomic groups: (?>...)

Используйте явные альтернативы. Например, вместо ^/((?!_next/static).*)$ используйте два маршрута с разными приоритетами.

ПараметрЛимит
Слоёв на деплой10
Маршрутов на деплой200
Middleware на деплой10
Длина паттерна500 символов
Длина name слоя64 символа
Длина directory256 символов
Длина entry512 символов
Размер meta (JSON)16 KB
ЗадачаPattern
Точный путь^/about$
С trailing slash^/about/?$
Dynamic segment^/blog/[^/]+$
Wildcard^/api/.*$
Catch-all^/.*$
Hashed assets^/_next/static/.*$
Multiple segments^/blog/[^/]+/comments$