
# Deploy API

Развёртывание приложений на BLACKHOLE-серверах без SSH. Все операции идут через агент туннеля: команды выполняются на сервере, файлы загружаются через туннель, логи читаются из системного журнала (утилита `journalctl`). AI-агенты должны использовать эту группу эндпоинтов для полного цикла «взять код из git → установить зависимости → запустить сервис → читать логи».

**Требования:** сервер в режиме `BLACKHOLE`, статус `running`, `blackholeStatus: CONNECTED`. В OPEN-режиме Deploy API вернёт `NOT_BLACKHOLE`.

Спящую отдельную виртуальную машину поднимать заранее не нужно: выкладка, команда, загрузка файла и чтение журнала будят сервер в статусе `sleeping` сами и ждут готовности в том же запросе — до 6.5 минут. Не уложился — приходит `503 WAKE_TIMEOUT`, сервер возвращается в `sleeping`, повторный запрос безопасен. Разбор — [Полный деплой приложения](./deploy/deploy.md), раздел «Известные особенности».

> **Это контракт для Black Hole VM (`kind: "STANDALONE"`).** Для galaxy-приложения (`kind: "GALAXY_APP"`) требование `CONNECTED` не действует — деплой сам собирает контейнер. Полная модель и контракт деплоя galaxy-приложения — [Galaxy-приложение](./galaxy.md).

> **OOM galaxy-приложения → выпуск на выделенный сервер.** Если деплой galaxy-приложения падает с `502 GALAXY_APP_START_FAILED` именно по причине OOM (приложение переросло лимит памяти контейнера 512 МБ), ответ содержит структурную подсказку `error.hint` с `recoveryAction: "graduate-to-dedicated-vm"`. Рекомендованное действие — пересоздать приложение на отдельной виртуальной машине: [`POST /v1/infra/servers`](/docs/infra/servers/create) с `placement: "dedicated"` и `graduateFrom` (идентификатор упавшего galaxy-приложения, который будет удалён после создания сервера), затем `POST /v1/infra/servers/:id/deploy` с тем же исходным кодом. Защита от повторного создания через заголовок `Idempotency-Key` на этот выпуск не распространяется — вместе с `graduateFrom` он вернёт `400 IDEMPOTENCY_UNSUPPORTED_WITH_GRADUATION`. Допустимо, когда политика `serverCreation` портала разрешает создание серверов и вы в пределах квоты, выделенная виртуальная машина тарифицируется (засыпает при простое). Подсказка добавляется только при причине OOM, а не при обычном краше.

**Формат ответов:** все эндпоинты по умолчанию отдают **JSON** (201/200 со `{"success": true, ...}`). Для `/deploy` и `/exec` доступен потоковый режим через `?stream=true` — возвращается поток SSE (Server-Sent Events) с построчным прогрессом. Для AI-агентов и MCP-клиентов **всегда используйте JSON** (не добавляйте `?stream=true`) — они не умеют разбирать SSE.

**Ограничения частоты:**

| Ограничение | Значение |
|-------------|----------|
| Операций в минуту на сервер | 10 |
| Одновременных `exec`/`deploy` | 1 на сервер |
| Таймаут `exec` | 1–600 секунд (по умолчанию 300) |
| Размер встроенного тела (base64 в `/upload`, `/deploy source.content`) | 96 МБ тела, около 72 МБ архива. Сверх потолка — `413 INLINE_SOURCE_TOO_LARGE` |
| Размер файла через URL (`/upload url`, `/deploy source.url`) | 500 МБ |
| Размер архива сохранённой версии (`/deploy source.versionId`) | 500 МБ |
| Размер multipart-архива в `/deploy` | 500 МБ, пока архив уходит в хранилище потоком. Иначе около 72 МБ — [условия](./deploy/deploy.md) |

Скоуп: `vibe:infra`

## Операции

- [Выполнить команду](./deploy/exec.md) — `POST /v1/infra/servers/:id/exec`
- [Загрузить файл](./deploy/upload.md) — `POST /v1/infra/servers/:id/upload`
- [Логи сервиса](./deploy/logs.md) — `GET /v1/infra/servers/:id/logs`
- [Полный деплой приложения](./deploy/deploy.md) — `POST /v1/infra/servers/:id/deploy`
- [Исход выкладки](./deploy/operation-status.md) — `GET /v1/infra/operations/:operationId`
- [Последние операции сервера](./deploy/operations.md) — `GET /v1/infra/servers/:id/operations`
- [Задать порт приложения](./deploy/port.md) — `PATCH /v1/infra/servers/:id/port`
- [Метрики туннеля](./deploy/metrics.md) — `GET /v1/infra/servers/:id/metrics`
- [Снять зависший лок](./deploy/lock.md) — `DELETE /v1/infra/servers/:id/lock`
- [Список рантаймов](./deploy/runtimes.md) — `GET /v1/infra/runtimes`

## Возможности

- [Быстрый цикл выпуска](./deploy/fast-cycle.md) — приёмы, сокращающие цикл повторных выпусков без полного прогона всех шагов

## Типовой сценарий

**Полный цикл деплоя в один запрос:**

1. [`POST /v1/infra/servers`](/docs/infra/servers/create) — создать сервер.
2. Подождать готовности через [`GET /v1/infra/servers/:id`](/docs/infra/servers/get) (`status: "running"` + `blackholeStatus: "CONNECTED"`).
3. [`POST /deploy`](./deploy/deploy.md) — указать `source.url` / `runtime` / `install` / `start` / `port`. Все шаги деплоя выполнятся автоматически. По умолчанию ответ JSON — `?stream=true` нужен только если хочется SSE.
4. После деплоя — [`GET /logs?lines=100`](./deploy/logs.md) для проверки.
5. При отладке — [`POST /exec`](./deploy/exec.md) для разовых команд.

**Ручной цикл (без `/deploy`):**

1. [`POST /upload { source.url }`](./deploy/upload.md) — положить архив, распаковать.
2. [`POST /exec { command: "cd /opt/app && npm install" }`](./deploy/exec.md) — зависимости.
3. [`POST /exec { command: "systemctl start app" }`](./deploy/exec.md) — старт сервиса.
4. [`GET /logs?service=app&lines=50`](./deploy/logs.md) — подтвердить работу.

[`POST /deploy`](./deploy/deploy.md) делает всё сразу и сам проверяет работоспособность приложения.

## Иконка приложения

Иконка приложения (SVG) показывается в каталоге Bitrix24 и как фавикон во вкладке браузера. Формат, требования и порядок (фавикон-`<link>` до деплоя, загрузка `POST /v1/infra/servers/:id/icon` после) вынесены на отдельную страницу — [Иконка приложения](/docs/infra/app-icon).

## Руководства

- [Загрузка дампа БД на сервер](/docs/recipes/db-dump-restore) — залить дамп и восстановить базу в фоне через `exec`.

## Смотрите также

- [Создание сервера](/docs/infra/servers/create)
- [Жизненный цикл](/docs/infra/lifecycle)
- [Переключить режим](/docs/infra/access/mode)
- [Корневой раздел — Инфраструктура](/docs/infra)
