layero deploy
Упаковывает cwd и публикует его как новый деплой проекта. Git и GitHub не требуются — CLI заливает локальную директорию напрямую.
Базовое использование
cd my-site
npx layero@latest deploy
Что происходит:
- CLI смотрит на папку и печатает, как её понял (событие
detected). Это подсказка: в проект уходит только то, что назвали вы (--type,--root, поля.layero/project.json), а фреймворк, команду сборки и папку результата платформа определяет сама — по загруженным файлам. - Обходит cwd, применяет правила игнорирования (см. ниже), пакует в tar.gz во временной директории и считает sha256 на лету.
- Архив заливается в Yandex Object Storage по presigned URL.
- Бэкенд создаёт деплой и запускает сборку.
- CLI поллит логи деплоя (
/deploys/{id}/logs) до статусаreadyилиfailed, выводя их в терминал. - Когда адрес уже отвечает сайтом, CLI печатает ссылку на него.
Первый layero deploy в новой папке создаст проект и запишет ./.layero/project.json. Последующие запуски используют тот же проект — никакого визарда в браузере, никакой ручной привязки.
Прежде чем выкатывать незнакомую папку, посмотрите план — он ничего не загружает и не требует входа:
npx layero@latest deploy --dry-run
Авто-детект фреймворка
CLI читает package.json и характерные конфиги:
| Сигнал | Фреймворк | build_cmd | output_dir |
|---|---|---|---|
next в deps / next.config.* | nextjs | npm run build (или npx next build) | out |
nuxt в deps / nuxt.config.* | nuxt | npm run generate если есть, иначе npm run build | .output/public |
@sveltejs/kit / svelte.config.js | sveltekit | npm run build | build |
gatsby в deps | gatsby | npm run build | public |
astro в deps / astro.config.* | astro | npm run build | dist |
@docusaurus/core / docusaurus.config.* | docusaurus | npm run build | build |
vite в deps / vite.config.* | vite | npm run build | dist |
react-scripts в deps | cra | npm run build | build |
index.html в корне, фреймворка нет | static | нет — файлы раздаются как есть | . |
package.json со скриптом build, фреймворк неизвестен | generic | npm run build | папка с index.html после сборки |
confident: false в событии detected значит, что папку не узнали, и тогда
в нём есть hint и next_action — что CLI увидел и что сделать:
| Что в папке | Что подсказывает CLI |
|---|---|
приложение в подпапке (apps/web) | --root apps/web |
| приложение в подпапке импортирует соседний пакет воркспейса | layero.json в корне: "framework": "generic", buildCommand, outputDirectory |
frontend/ и backend/ рядом | layero.json с блоками frontend и backend |
| свой скрипт сборки без известного фреймворка | "framework": "generic" — при static сборка не запускается |
| сервер без известного фреймворка | -t node_web / -t python_web |
Если детект ошибся, передайте --type явно: статический пресет (--type vite) или тип рантайма для сервера (-t node_web, -t python_web). Приложение лежит в подпапке монорепо — --root apps/web. Чтобы исправление ехало вместе с кодом, положите в репозиторий layero.json — там же таблица «симптом → что править». CLI учитывает значения из layero.json и в detected, и в --dry-run.
С 0.11.0 CLI не записывает догадку детекта ни в проект, ни в
.layero/project.json. Раньше первая выкатка сохраняла её в настройки проекта,
и в логе сборки она выглядела как (from hint) / (from dashboard). Поля
framework_hint, build_cmd, output_dir в .layero/project.json — ваши:
впишите их руками, и новый проект получит их как ваш выбор.
Флаги
| Флаг | Описание |
|---|---|
--dry-run | Показать план сборки и выйти: фреймворк, команда сборки, папка результата, источник каждого значения (layero.json, настройки проекта, package.json, умолчание фреймворка), подсказки по форме папки и то, заменит ли выкатка живой сайт. Ничего не загружает, вход не нужен; если вход выполнен, читает и настройки привязанного проекта. Событие — plan. |
--prod | Только для проекта с подключённым репозиторием: сделать эту загрузку живой — адрес проекта переключится на неё. Без флага такая загрузка ляжет в отдельное окружение cli. Проект без репозитория публикуется всегда, флаг ему не нужен. |
--promote | После успешной сборки перевести живой адрес на эту загрузку (то же, что --prod, но это делает сам CLI, отдельным запросом). Проекту без репозитория не нужен. |
--branch <name> | Отклоняется кодом branch_unsupported (код выхода 4): архивные загрузки всегда идут в окружение cli (см. ниже), и флаг превью дать не может. Осмыслен только у layero promote --branch. |
--claim | Деплой без аккаунта: временный сайт на час и claim_url, по которому человек заберёт сайт. Только статика и SPA: серверное приложение (SSR, фуллстек, контейнер) отклоняется до выгрузки кодом claim_static_only (код выхода 4). Адрес случайный — имя папки и --name в него не попадают; поисковикам сайт закрыт (robots.txt с Disallow: / и X-Robots-Tag: noindex, nofollow). Только явным флагом: без --claim и без токена deploy просит войти (auth_required) — и в агентской среде тоже. Токен, код заявки и ссылка хранятся в ~/.layero/config.json, а не в .layero/project.json: этот файл уходит в git. Забор сайта в аккаунт сбрасывает переменные окружения, хуки деплоя и настройки сборки, заведённые без аккаунта. Вместе с --project отклоняется кодом claim_with_project (код выхода 4). |
--prebuilt [dir] | Отправить готовую сборку вместо сборки на платформе. Без аргумента берётся первый существующий из dist/, build/, public/, out/, _site/. Правила .gitignore и .layeroignore при этом не применяются — см. врезку ниже. |
-t, --type <preset> | Оверрайд авто-детекта. Статический пресет говорит, чем собирать: vite, vitepress, next, astro, cra, sveltekit, nuxt, gatsby, docusaurus, storybook, eleventy, hugo, static (сборка не запускается вовсе), generic (свой build-скрипт: исполняются buildCommand и outputDirectory из layero.json). Тип рантайма говорит, что приложение надо запускать в контейнере, а не раздавать файлами: node_web, python_web, ssr_next, streamlit, gradio, flask; синонимы — express, fastapi, django, node, python. Неизвестное значение — отказ invalid_type. |
--root <dir> | Монорепо: подпапка репозитория, которую сборщик считает корнем приложения, например --root apps/web. Сохраняется на проекте — сборки по push и по хукам возьмут то же значение. Ключа для этого в layero.json нет. |
--name <name> | Имя проекта. Только при первом деплое. |
--project <id_or_slug> | Деплоить в конкретный проект, игнорируя ./.layero/project.json. Удобно для CI. |
--org <slug> | Создать проект в указанной Layero-организации (при первом деплое). |
--yes, -y | Пропустить подтверждение --prod / --promote и интерактивные вопросы. |
--json | JSON-lines на stdout (для AI-агентов и CI). |
--config | Legacy alias текущего поведения (авто-детект + .layero/project.json). |
--confirm-repeated-failure | Продолжить, хотя последние деплои падают с одной и той же ошибкой: платформа останавливает такие повторы, пока вы не подтвердите, что знаете, что изменилось. Флаг для человека, не для агента. |
Куда приземляется деплой
# CLI-проект (без подключённого репозитория): публикуется в apex АВТОМАТИЧЕСКИ.
# Прямые загрузки авто-промоутятся — отдельный --prod / promote не нужен.
npx layero@latest deploy
# → production-адрес проекта (живой публичный адрес; печатается в выводе)
# Проект с подключённым репозиторием: выложить загрузку на живой адрес (CI)
npx layero@latest deploy --prod --yes
Для CLI-проекта (без репозитория) каждый layero deploy заменяет то, что
отдаёт apex — это и есть публикация. Адрес работает сразу после первого
успешного билда: прогрева CDN, который раньше занимал несколько минут, больше
нет — пользовательские сайты идут напрямую на edge платформы.
Конкретный вид адреса зависит от того, в какой доменной зоне живёт проект
(<project>.layero.app или, у проектов старше 26 июля 2026, <org>-<project>.layero.app) — см.
Окружения, preview и production. Не собирайте
адрес по шаблону: берите его из поля url события ready.
Чем --prod отличается от --promote (актуально для проектов с
репозиторием; у проекта без репозитория живой адрес переключается и так):
--prod— платформа переводит живой адрес на эту загрузку сама, когда сборка готова.--promote— CLI сам переводит адрес после сборки, отдельным запросом. Результат тот же.
--branch в layero deploy отклоняетсяАрхивные загрузки бэкенд всегда кладёт в зарезервированное окружение
cli — чтобы ручная загрузка не столкнулась с веткой подключённого
репозитория. До 0.10.0 флаг принимался и молча игнорировался: после
layero deploy --branch=probe окружение probe не создавалось, а живой сайт
заменялся. С 0.10.0 CLI отказывает до упаковки — branch_unsupported, код
выхода 4 — и в next_action говорит, что делать: подключить репозиторий
(layero projects create --repo …) и пушить в ветку.
Что это значит на практике:
- Проект без репозитория.
cliу него и есть ветка по умолчанию, поэтому деплой авто-промоутится на апекс. Каждыйlayero deployзаменяет живой сайт, и способа загрузить непромоутящую версию из CLI нет. - Проект с подключённым репозиторием.
cli— не дефолтная ветка, поэтому CLI-загрузка живёт на отдельном адресе<проект>-cliи апекс не двигает (пока не передан--prod).
Превью веток — это git-путь: пуш в ветку создаёт окружение через вебхук.
--prebuilt не смотрит в .gitignoreФлаг указывает на каталог готовой сборки, где правила исходного дерева
бессмысленны, поэтому .gitignore и .layeroignore там не применяются. Это
задумано — но у этого есть обратная сторона.
layero deploy --prebuilt . на корне проекта опубликует всё, что там
лежит, кроме встроенного списка исключений, — включая черновики и заметки,
которые вы спрятали через .gitignore. Проверено на живом деплое: файл из
.gitignore после такой команды отдаётся с кодом 200.
Секреты при этом в безопасности: .env, .env.*, .git, node_modules и
файлы правил исключены и на этом пути тоже (проверено, включая вложенные
каталоги). Но каталог для --prebuilt всё равно стоит указывать явно.
Mixed-mode: GitHub + CLI на одном проекте
Один и тот же проект может одновременно принимать:
- push в GitHub → автоматический деплой (webhook)
layero deploy→ CLI-загрузка тарбола
GitHub-интеграция — необязательна. Первый деплой через CLI не требует ни git-репозитория, ни GitHub-аккаунта. Подключить GitHub можно потом, через дашборд, если захочется auto-deploy on push.
Mixed-mode удобен, когда:
- GitHub-build долгий или нестабильный, и нужен быстрый локальный hot-fix:
layero deploy --prod --yesподнимет ваш локальный код в production за секунды без коммита. - В CI после успешного теста хочется явно зафиксировать релиз:
layero deploy --prod --yesпослеgit push.
Артефакты в дашборде помечаются источником:
| Бейдж | Что значит |
|---|---|
push | Webhook от GitHub push |
cli | Загружен через layero deploy |
manual | Запущен через дашборд (Redeploy) |
Пример CI-сборки:
LAYERO_TOKEN=$LAYERO_DEPLOY_TOKEN npx layero@latest deploy --prod --yes \
--project alice-my-site
JSON-режим для агентов и CI
Любая команда CLI поддерживает --json (или LAYERO_JSON=1):
npx layero@latest deploy --json
Каждая строка stdout — JSON-объект с полем event:
{"event":"detected","framework":"vite","build_cmd":"npm run build","output_dir":"dist","confident":true,"sources":{"framework":"detected","build_cmd":"package.json","output_dir":"framework default"}}
{"event":"project_created","project_id":"...","slug":"my-site","organization":"alice"}
{"event":"packing","files":124,"bytes":2401234,"sha256":"..."}
{"event":"uploading"}
{"event":"deploy_started","deploy_id":"..."}
{"event":"build_log","line":"...","stream":"stdout"}
{"event":"ready","url":"https://my-site.layero.app/","dashboard_url":"https://app.layero.ru/projects/...","deploy_id":"..."}
url — живой публичный сайт (apex), открывать нужно именно его.
dashboard_url — страница управления, НЕ сам сайт.
Ошибки приходят со стабильным code и next_action:
{"event":"error","code":"cli_deploys_disabled","next_action":"enable them in project settings","message":"CLI deploys are disabled on project \"my-site\""}
Не залогинены?
layero deployсам запустит device-flow (событиеauth_required→ клик по ссылке → poll), отдельныйlayero loginне нужен.
В событии ready:
url— живой публичный сайт. У проекта без репозитория это адрес проекта (прямые загрузки публикуются сразу); у проекта с репозиторием без--prod— адрес окруженияcli.edge_ready— отвечает ли адрес уже самим сайтом. Прежде чем напечататьready, CLI сам ждёт этого до 90 секунд: приложению в контейнере нужно время на запуск.falseзначит, что приложение так и не ответило. Смотрите лог приложения:npx layero@latest logs --runtime.dashboard_url— страница управления, не сам сайт.
Подробнее — JSON-events схема.
JSON-режим включается автоматически когда CLI запущен внутри Cursor / Claude Code / любого процесса с не-TTY stdout. Подробнее — Деплой из AI-агентов, полный список событий — JSON-events схема.
Правила игнорирования
CLI уважает:
-
.gitignore(как git) -
.layeroignore(тот же синтаксис, можно расширять/исключать) -
встроенный denylist:
node_modules.gitdistbuild.next.env*.DS_Store.gitignore.layeroignoreСами файлы правил исключены намеренно: на сайте им делать нечего, а перечисляют они ровно те имена, которые вы решили спрятать — опубликованный
.gitignoreподсказывает, что искать.
Артефакты сборки (dist, build, .next) не нужно заливать — сборка запускается на стороне Layero после распаковки.
Лимиты
- Максимальный размер архива — 500 MB.
- Время
layero deployограничено таймаутами на бэкенде:Стадия Лимит clone / unpack 15 мин install 30 мин build 15 мин upload в S3 10 мин
Если ваш билд не укладывается — напишите в поддержку, лимиты повышаются индивидуально.
Окружение сборки
Каждая сборка запускается в изолированной песочнице на выделенной builder-VM:
- CPU / память: 2 vCPU, 4 GB RAM, swap до 4 GB, лимит процессов — 1024.
- Диск: writable scratch (
/mnt/scratch, ~40 GB на одну сборку), tmpfs/tmp256 MB. Кэшиnpm/yarn/pnpmавтоматически перенаправляются на scratch — большие бинарники (rolldown,swc,sharp) скачиваются без ENOSPC. - Сеть: разрешён исходящий HTTPS к npm-зеркалу, GitHub, реестрам пакетов (npm, yarn) и S3. Произвольные внешние эндпоинты с этапа сборки недоступны — это защищает чужие билды от случайного или вредоносного трафика. Если вашему билду нужен доступ к закрытому реестру или CDN, напишите в поддержку.
- Изоляция: gVisor (
runsc) + seccomp + drop-all capabilities + read-only rootfs. Сборки разных проектов не видят друг друга и не имеют доступа к инфраструктуре Layero.
Среда не персистентна между билдами: всё, что вы записали в /tmp или /mnt/scratch, исчезает после завершения. Артефакты в output_dir (dist по умолчанию) загружаются в объектное хранилище, откуда их и раздаёт edge платформы.
После деплоя
После ready:
- Preview-URL ветки доступен сразу после успешной сборки и живёт, пока существует сама ветка.
- Apex (production-адрес проекта) отдаёт этот деплой, если он стал production: для CLI-проекта (без репозитория) это происходит автоматически на каждом
layero deploy; для git-проекта — через auto-promote default-ветки или--promote.--branchна это не влияет — см. врезку выше.
См. Окружения, preview и production для полной картины.
Postinstall-баннер
После npm install -g layero или npm install -D layero (без --silent) CLI пишет краткий quick-start в /dev/tty. В CI-окружениях баннер подавляется автоматически (CI=1). Чтобы выключить вручную:
LAYERO_SKIP_POSTINSTALL=1 npm install -D layero