
# Galaxy-приложение

Galaxy-приложение — это отдельное приложение Black Hole, которое живёт в контейнере на общем хосте — галактике — вместе с другими такими же приложениями. Каждое приложение получает свой HTTPS-субдомен и изоляцию, как у отдельной виртуальной машины, но все они делят одну галактику — это кратно дешевле, чем держать отдельный сервер под каждое приложение. Если администратор портала включил размещение в галактиках, тот же вызов `POST /v1/infra/servers` создаёт galaxy-приложение, а не виртуальную машину.

**Скоуп:** `vibe:infra` · **Базовый URL:** `https://vibecode.bitrix24.tech/v1` · **Авторизация:** заголовок `X-Api-Key`

## Кто выбирает модель размещения

Режим размещения выбирает администратор портала в кабинете на странице «Галактики», в разделе «Режим размещения приложений». Обычный участник портала видит режим только для чтения, а вызывающий API его не задаёт. Один и тот же запрос `POST /v1/infra/servers` создаёт либо отдельную виртуальную машину, либо galaxy-приложение, в зависимости от режима портала. Параметра «создать именно galaxy-приложение» в запросе нет.

Режим портала — один из трёх:

- **Сначала галактика** (`galaxies-only`) — новые приложения размещаются плотно внутри галактик. Если приложение перерастает свой контейнер, его переносят на отдельный сервер Black Hole.
- **Гибридный режим** (`both`) — приложение попадает в галактику, когда в ней есть место, иначе разворачивается на отдельной виртуальной машине.
- **Отдельные серверы** (`standalone-only`) — галактики не используются, каждое приложение получает свою виртуальную машину.

Что с этим делать вызывающему:

- **Определяйте модель по ответу, а не задавайте её.** Признак galaxy-приложения — поле `createdVia` равно `galaxy` в ответе создания. Полный список признаков — в разделе «Как отличить galaxy-приложение в ответе» ниже.
- **Нужна именно отдельная виртуальная машина — запросите её явно.** Если портал размещает приложения в галактиках, но конкретному приложению нужен выделенный сервер, передайте в теле [`POST /v1/infra/servers`](./servers/create.md) поле `placement` равным `dedicated` — платформа создаст отдельную виртуальную машину вместо galaxy-приложения. По умолчанию `placement` равен `auto`, и применяется настройка портала.

На бесплатном тарифе Битрикс24 галактика не создаётся:

- Если у аккаунта Битрикс24 **уже есть** галактика, приложения по-прежнему разворачиваются в ней — ограничение касается только создания новой.
- Если галактики нет, каждое приложение получает отдельную виртуальную машину, а одношаговое создание с полем `source` вернёт `400 SOURCE_AT_CREATE_GALAXY_ONLY`. Разворачивайте в два шага: [`POST /v1/infra/servers`](./servers/create.md) без `source`, затем [`POST /v1/infra/servers/:id/deploy`](./deploy/deploy.md).
- Коммерческий тариф Битрикс24 снимает ограничение.

Готовность у моделей разная:

- **Отдельная виртуальная машина** — по `status: "running"` и `blackholeStatus: "CONNECTED"`.
- **Galaxy-приложение** — только через загрузку кода, ожидание `CONNECTED` здесь не работает (см. «Жизненный цикл» ниже).

## Доступность галактик

Галактики включаются в два шага, и оба делаются на стороне Вайбкод: сначала команда платформы включает их на платформе, затем администратор портала — для своего портала. Приложения размещаются в галактиках только тогда, когда сделаны оба шага. Признак до вызова — блок `deployment` в ответе [`GET /v1/me`](/docs/keys-auth/me):

- `galaxyEnabled` — открыты ли галактики порталу. Значение `false` означает, что не сделан хотя бы один из двух шагов.
- `galaxyApp` — вложенный блок с контрактом деплоя galaxy-приложения. Приходит, когда галактики открыты и режим размещения не «Отдельные серверы». В остальных случаях блока в ответе нет совсем.
- `primary` — модель размещения, которую платформа считает основной для этого портала: `galaxyApp` или `standalone`.

Поле `resolvedDeployMode` показывает режим размещения, выбранный в кабинете, и приходит заполненным независимо от доступности. Значение `both` при `galaxyEnabled` равном `false` означает, что режим в кабинете выбран, но галактики порталу не открыты — приложения разворачиваются на отдельных виртуальных машинах.

Порядок включения:

1. **Команда платформы** включает галактики на платформе. Пока этого не сделано, переключателя «Галактики» в разделе «Настройки» кабинета не видно — включить их самостоятельно нельзя, обратитесь в поддержку.
2. **Администратор портала** включает галактики для своего портала — переключателем «Галактики» в том же разделе «Настройки». Обычный участник портала эту настройку не меняет.

Стоимость и лимиты у galaxy-приложения считаются иначе, чем у отдельной виртуальной машины — см. раздел «Стоимость» ниже.

## Как отличить galaxy-приложение в ответе

| Поле | Где | Значение |
|------|-----|----------|
| `createdVia` | ответ [`POST /v1/infra/servers`](./servers/create.md) | `galaxy` для galaxy-приложения |
| `kind` | ответ `POST /v1/infra/servers` и [`GET /v1/infra/servers/:id`](./servers/get.md) | `GALAXY_APP` — galaxy-приложение (контейнер), `GALAXY` — галактика (хост-носитель), `STANDALONE` — отдельная виртуальная машина |
| `galaxyId` | ответ `POST /v1/infra/servers` и [`GET /v1/infra/servers/:id`](./servers/get.md) | ID галактики, в которой размещено приложение. Для остальных типов `null` |
| `appCount` | ответ [`GET /v1/infra/servers/:id`](./servers/get.md) | Для галактики (`GALAXY`) — число неудалённых приложений в ней. Для остальных типов `null` |

У galaxy-приложения нет своего SSH-доступа (`ssh` равно `null`), публичного IP-адреса и внешнего идентификатора виртуальной машины — у контейнера их нет. Поля `region` и `plan` в ответе — это регион и тариф галактики-носителя: переданные при создании значения ни на что не влияют, размещение платформа выбирает сама.

## Жизненный цикл — сборка при загрузке кода

Galaxy-приложение **никогда** само не доходит до `blackholeStatus: "CONNECTED"`. Его контейнер и агент туннеля создаёт сама загрузка кода — отдельного шага провижининга, как у виртуальной машины, здесь нет.

Из этого следует главное правило: **загружайте код сразу после создания, не дожидаясь `CONNECTED`.** Если создать galaxy-приложение и просто опрашивать статус, оно останется в `provisioning`, а примерно через 20 минут платформа пометит его как `error` и запишет в поле `provisionError`, что код так и не был загружен.

## Создание и загрузка кода

Создание идёт тем же вызовом [`POST /v1/infra/servers`](./servers/create.md). Код загружают одним из двух сценариев.

- **Сценарий 1 — одним запросом.** Передайте код в поле `source` вместе с `runtime` и `start` прямо в `POST /v1/infra/servers`. Сборка пойдёт в фоновом режиме, отдельный вызов загрузки не нужен.
- **Сценарий 2 — в два шага.** Создайте приложение без `source`, получите в ответе `next: "deploy"`, затем загрузите код через [`POST /v1/infra/servers/:id/deploy`](./deploy/deploy.md). Создание без `source` требует `provider`/`plan`/`region` (для galaxy они информационны — см. [пример в create.md](./servers/create.md)).

Полные тела запросов, поля и примеры для обоих сценариев — на странице [Создать сервер](./servers/create.md).

Создание galaxy-приложения по сценарию 1 — `source` передан, сборка идёт в фоне. Признак модели — `createdVia` равно `galaxy`:

```json
{
  "success": true,
  "data": {
    "id": "7c2b1f08-3a4d-4e91-9b6c-2f5e8a1d0c33",
    "status": "provisioning",
    "name": "my-crm-app",
    "kind": "GALAXY_APP",
    "galaxyId": "<galaxy-host-id>",
    "ssh": null,
    "ip": null,
    "plan": "bc-medium",
    "region": "ru-central1-a",
    "mode": "BLACKHOLE",
    "createdVia": "galaxy",
    "subdomain": "app-7c2b1f08",
    "blackholeStatus": "NONE",
    "appUrl": "https://app-7c2b1f08.vibecode.bitrix24.tech",
    "createdAt": "2026-04-22T10:50:11.477Z"
  }
}
```

## Деплой

Деплой galaxy-приложения отличается от деплоя виртуальной машины. Полный контракт — на странице [Полный деплой приложения](./deploy/deploy.md).

- Источник кода — встроенный `source.content` (архив в base64). Варианты `source.url` и `source.versionId` доступны там, где платформа включила для вас выкладку по ссылке. Иначе они отклоняются с `400 GALAXY_DEPLOY_CONTENT_ONLY`. По ссылке архив скачивает сам хост, поэтому крупный архив не проезжает через тело запроса. Ссылка обязана вести в [хранилище исходников](/docs/source-storage) — сторонний адрес отклоняется с `400 GALAXY_SOURCE_URL_NOT_ALLOWED`, поэтому крупный архив сначала сохраняют версией, а выкладывают по `source.versionId`.
- Поля `runtime` и `start` обязательны. Без `runtime` запрос вернёт `400 GALAXY_DEPLOY_RUNTIME_REQUIRED`. Список рантаймов — [`GET /v1/infra/runtimes`](./deploy/runtimes.md).
- Свой `Dockerfile` класть не нужно — платформа генерирует его из полей `runtime`, `port` и `start`.
- Переменные `env` подставляются в контейнер при запуске, а не вшиваются в образ, поэтому секреты не попадают в слои образа. Рядом с ними платформа добавляет `PORT` — номер порта приложения. Ключ `PORT` зарезервирован, подробности в [POST /v1/infra/servers/:id/deploy](./deploy/deploy.md).
- Рабочая директория контейнера — `/opt/app`, путь `/app` тоже ведёт на неё как ссылка. Постоянные данные сохраняйте в томе `/data`.

## Управление жизненным циклом

Galaxy-приложение живёт в контейнере на общем хосте и своей облачной машины не имеет. Поэтому часть операций жизненного цикла работает через хост, а часть к приложению не применяется. Полная карта — ниже, на страницах самих операций остаётся только то, что специфично для вызова.

| Операция | Что происходит с galaxy-приложением |
|----------|-------------------------------------|
| [`POST /:id/start`](./lifecycle/start.md), [`POST /:id/wake`](./lifecycle/wake.md) | Поднимают приложение через хост: платформа при необходимости запускает галактику, затем стартует контейнер. Ответ приходит сразу, готовность проверяйте опросом [`GET /v1/infra/servers/:id`](./servers/get.md) — параметр `?wait=true` ожидания здесь не даёт. Запрет пробуждения на хосте блокирует оба вызова, и `/start` его не снимает: отказ приходит с кодом `403 SERVER_WAKE_BLOCKED`, а когда причина в подписке или тарифе аккаунта — со статусом `402` и кодом соответствующего отказа доступа. Приложение в статусе `error` лечит повторный деплой, а не эти вызовы |
| [`POST /:id/reboot`](./lifecycle/reboot.md) | Перезапускает контейнер на хосте. Постоянный том `/data` сохраняется |
| [`POST /:id/stop`](./lifecycle/stop.md) | Не применяется. Работающее приложение получает `422 VM_MISSING` — останавливать нечего, машины у контейнера нет. Приложение вне статуса `running` отвечает раньше, `422 SERVER_WRONG_STATE`. Чтобы снять приложение, вызовите [`DELETE /v1/infra/servers/:id`](./servers/delete.md) |
| [`PATCH /:id/sleep`](./lifecycle/sleep.md) | Не применяется — `400 GALAXY_APP_USE_GALAXY_ROUTE`. Приложение засыпает вместе с хостом, таймер простоя через API Вайбкод ему не задаётся |
| [`POST /:id/sleep-now`](./lifecycle/sleep-now.md) | Не применяется — `400 GALAXY_APP_USE_GALAXY_ROUTE` |
| [`PATCH /:id/port`](./deploy/port.md) | Не применяется — `400 GALAXY_APP_USE_GALAXY_ROUTE`. Порт контейнера закреплён за хостом и задаётся полем `port` при [загрузке кода](./deploy/deploy.md) |
| [`POST /:id/repair`](./lifecycle/repair.md) | Не применяется — `400 INVALID_INPUT`. Ремонт переустанавливает агента на облачной машине, а у контейнера её нет |
| [`POST /:id/refresh`](./lifecycle/refresh.md) | Отвечает текущим статусом записи. У облака состояние не запрашивается — запрашивать нечего |
| Окна пробуждения: [создать](./wake-schedules/create.md), [изменить](./wake-schedules/update.md) | `403 WAKE_SCHEDULE_GALAXY_DISABLED`, пока возможность не раскрыта для приложений |
| [`DELETE /:id`](./servers/delete.md) | Работает — платформа разбирает контейнер в галактике. Подробности в разделе «Удаление» ниже |

Три вызова из таблицы — `PATCH /:id/sleep`, `POST /:id/sleep-now` и `PATCH /:id/port` — отвечают одним кодом `GALAXY_APP_USE_GALAXY_ROUTE`. Тип сервера проверяется раньше статуса и режима, поэтому приложение получает этот код в любом состоянии, а не `NOT_RUNNING` и не `404`. Раньше проверки типа идут только проверки значений в запросе: недопустимый `sleepAfterMinutes` или `port` вне диапазона `0–65535` дадут `VALIDATION_ERROR` и на galaxy-приложении, а системный порт `1–1023` — `PORT_RESTRICTED`.

## Команды, выкладка и файлы — по id приложения

Список серверов отдаёт и приложение (`kind: "GALAXY_APP"`), и несущую его машину (`kind: "GALAXY"`), поэтому у вызывающего на руках два разных id. Работать надо с id приложения. Машина общая: на ней стоят контейнеры других ключей того же аккаунта Битрикс24, поэтому клиентские операции по её id платформа отклоняет.

| Операция | По id приложения (`kind: "GALAXY_APP"`) | По id машины (`kind: "GALAXY"`) |
|----------|------------------------------------------|----------------------------------|
| [`POST /:id/exec`](./deploy/exec.md) | Работает — команда выполняется внутри контейнера приложения. Поля `workdir` и `env` не поддерживаются: `400 GALAXY_EXEC_NO_WORKDIR_ENV`. Вместо них добавьте приставку к самой команде: `cd /opt/app; FOO=bar node script.js` | `403 GALAXY_HOST_EXEC_FORBIDDEN` |
| [`POST /:id/deploy`](./deploy/deploy.md) | Работает — это основной способ выложить код, см. раздел «Деплой» выше | `400 GALAXY_HOST_NOT_A_DEPLOY_TARGET` |
| [`POST /:id/upload`](./deploy/upload.md) | Не применяется: своего туннеля у контейнера нет, и вызов не проходит проверку готовности сервера. Файлы кладите в архив деплоя либо создавайте их командой через `/exec` | `400 GALAXY_HOST_NOT_A_DEPLOY_TARGET` |

Отказ по id машины приходит до того, как платформа что-либо сделает с сервером, и блокировки на нём не оставляет — повторять тот же вызов бесполезно. Возьмите в [списке серверов](./servers/list.md) строку своего приложения (`kind` равен `GALAXY_APP`) и обращайтесь по её id.

Чтение журнала гейт не затрагивает: [`GET /:id/logs`](./deploy/logs.md) по id машины по-прежнему отдаёт её системный журнал.

## Свободное место в галактике

Занятость диска машины-галактики видна в кабинете, на карточке галактики в разделе «Галактики»: сколько занято из общего объёма и когда сделан замер. Спящую машину платформа не опрашивает и показывает последнее известное значение — поэтому время замера стоит рядом с самой величиной. Когда свободного места остаётся мало, на карточке появляется подсказка с двумя действиями, которые у вас уже есть: расширить диск галактики или перевезти приложение на другую галактику.

Раньше эту величину получали командой `df` по id машины — теперь такой вызов отклоняется (`403 GALAXY_HOST_EXEC_FORBIDDEN`). Вместо него строка машины-галактики в [`GET /v1/infra/servers`](./servers/list.md) и в [карточке сервера](./servers/get.md) несёт четыре поля:

| Поле | Что означает |
|---|---|
| `diskTotalMb` | размер диска в мебибайтах |
| `diskFreeMb` | свободное место в мебибайтах |
| `diskState` | оценка: `ok`, `warning`, `critical` или `unknown`, если замера ещё не было |
| `diskProbedAt` | время замера в формате ISO-8601 |

Оценку считает та же величина, что решает, хватит ли места на сборку приложения: `critical` означает, что свободного места меньше этого порога и сборка будет отклонена, `warning` — что вы к нему подходите. Поэтому предупреждение приходит заранее, до первого отказа. У машин вида `STANDALONE` и у приложений галактики все четыре поля равны `null`: у первых диск не измеряется, у вторых своего диска нет.

## Исходящий IP

У galaxy-приложения нет собственного статического исходящего IP-адреса. Запросы приложения наружу — к внешним базам данных, платёжным шлюзам, сторонним сервисам — уходят через общий публичный IP хоста-галактики, который делят все приложения на этом хосте.

Этот адрес динамический. Платформа сама выбирает размещение, и исходящий IP может измениться при остановке и пробуждении хоста, плановом перезапуске инфраструктуры и при переносе приложения на другую галактику. Отдельного эндпоинта, который возвращает исходящий IP приложения, нет.

У отдельной виртуальной машины собственный публичный адрес есть — он приходит в поле `ip` ответа [`GET /v1/infra/servers/:id`](./servers/get.md). За машиной он не закреплён: при каждом пробуждении машина получает адрес заново, поэтому после нескольких циклов сна `ip` в карточке сервера отдаёт другое значение. Это относится ко всем тарифам, включая невытесняемые.

Постоянного исходящего адреса платформа не даёт ни в одной модели размещения. Список разрешённых IP на стороне внешнего сервиса — например управляемого PostgreSQL — перестанет совпадать с фактическим адресом и у galaxy-приложения, и у отдельной виртуальной машины.

## Стоимость

Стоимость считается за галактику, а не за каждое приложение. Несколько galaxy-приложений в одной галактике делят её стоимость — пять приложений на тарифе `bc-small` обходятся примерно как одна галактика, а не как пять серверов. В лимит серверов на API-ключ (`GET /v1/me` → `infra.limits.used`) galaxy-приложения не входят — он считает только отдельные виртуальные машины.

## Логи

Для galaxy-приложения [`GET /v1/infra/servers/:id/logs`](./deploy/logs.md) возвращает поток вывода самого контейнера (`stdout` и `stderr`), а не системный журнал галактики. Чтение логов не будит спящую галактику. Если галактика спит или недоступна, ответ — пустой массив `data.logs` плюс диагностическое поле `data.hint`. Параметр `since` для galaxy-приложения принимает только длительность (`10m`, `2h`, `24h`) или метку времени в формате RFC 3339 (например, `2026-04-22T10:50:11Z`).

## Удаление

Galaxy-приложение снимается тем же вызовом [`DELETE /v1/infra/servers/:id`](./servers/delete.md) — платформа разбирает его контейнер в галактике и помечает запись удалённой. Спящую галактику платформа будит сама перед удалением. Галактика с неудалёнными приложениями этим вызовом не удаляется — сначала снимите её приложения.

## Коды ошибок

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `GALAXY_APP_USE_GALAXY_ROUTE` | На galaxy-приложение пришёл вызов, который относится к отдельной виртуальной машине — `PATCH /:id/sleep`, `POST /:id/sleep-now` или `PATCH /:id/port`. Что применимо к приложению — в разделе «Управление жизненным циклом» выше |
| 403 | `GALAXY_HOST_EXEC_FORBIDDEN` | Команда пришла на id машины-галактики (`kind` равен `GALAXY`). Выполняйте её на приложении, по его собственному id — см. раздел «Команды, выкладка и файлы» выше |
| 400 | `GALAXY_HOST_NOT_A_DEPLOY_TARGET` | Деплой или загрузка файла пришли на id машины-галактики (`kind` равен `GALAXY`). Машина — носитель контейнеров, а не цель выкладки: обращайтесь по id приложения |
| 400 | `GALAXY_EXEC_NO_WORKDIR_ENV` | В команде для galaxy-приложения переданы `workdir` или `env` — контейнерный запуск их не принимает. Добавьте приставку к самой команде: `cd /opt/app; FOO=bar node script.js` |
| 400 | `SOURCE_AT_CREATE_GALAXY_ONLY` | Поле `source` передано при создании на портале без режима галактик либо вместе с `placement: "dedicated"`. Загружайте код через [`POST /:id/deploy`](./deploy/deploy.md) после создания |
| 400 | `GALAXY_DEPLOY_CONTENT_ONLY` | Деплой galaxy-приложения с `source.url` или `source.versionId` там, где выкладка по ссылке для вас не включена. Пришлите архив встроенным `source.content` |
| 400 | `GALAXY_DEPLOY_RUNTIME_REQUIRED` | Деплой galaxy-приложения без `runtime`. Укажите рантайм, например `node20` |
| 502 | `GALAXY_BASE_IMAGE_UNAVAILABLE` | Сборка не смогла получить базовый образ — склад образов был недоступен. Состояние временное, повторите тот же деплой через 2–3 минуты, см. [Загрузить код](./deploy/deploy.md) |
| 502 | `GALAXY_LOW_DISK` | На хосте кончилось свободное место во время сборки. Состояние повторяемое: приложение сломанным не помечается, слот и том `/data` целы, а уже работающая версия продолжает обслуживать запросы. Повторяйте деплой после того, как на хосте освободили место, см. [Загрузить код](./deploy/deploy.md). Исключение — создание сервера сразу с полем `source`: там приложение помечается сломанным |
| 502 | `GALAXY_APP_BUILD_FAILED` | Сборка контейнера не удалась. Хвост лога сборки приходит в поле `buildLog`, а разбор причины — в `error.category` и `error.buildHint`, см. [Загрузить код](./deploy/deploy.md) |
| 502 | `GALAXY_APP_START_FAILED` | Контейнер собрался, но упал или ушёл в перезапуск по нехватке памяти сразу после старта. Хвост лога приходит в поле `buildLog`, а разбор причины — в `error.category` и `error.buildHint`, см. [Загрузить код](./deploy/deploy.md) |
| 409 | `GALAXY_FULL` | Места под ещё одно galaxy-приложение нет. Прежде чем отказать, платформа пробует разместить приложение на другой галактике, поэтому этот ответ означает, что места действительно нет. Удалите ненужное galaxy-приложение либо запросите отдельную машину — поле `placement` со значением `dedicated`, см. [Создать сервер](./servers/create.md) |
| 409 | `GALAXY_HAS_APPS` | Удаляемый сервер — галактика, на которой есть неудалённые приложения. Тело содержит `appCount`. Удалить галактику вместе с приложениями можно в кабинете |
| 409 | `GALAXY_HOST_WAKE_BLOCKED` | Приложение удаляют на галактике, которую ЗАПРЕЩЕНО будить — например, заморожен счёт. Отказ терминальный: повтор не поможет, пока причина не снята. Причина приходит в `error.reason` — `BILLING_FROZEN`, `ACCESS_EXPIRED`, `STOPPED` или `UNKNOWN`. Поля `error.hint` в этом ответе нет |
| 502 | `GALAXY_DEPLOY_INTERRUPTED` | Деплой не подтверждён. Слот приложения и том `/data` сохранены — повторите тот же запрос. Поле `error.subcause` называет причину (`http_window_exhausted`, `exec_channel_busy`, `no_this_deploy_container`, `tail_unreached`, `source_fetch_interrupted`), а `error.repeated` показывает, что это уже не первое прерывание подряд — тогда разбирайте запуск самого приложения либо обращайтесь в поддержку, см. [Загрузить код](./deploy/deploy.md) |
| 502 | `GALAXY_HOST_UNREACHABLE` | Галактика недоступна — её туннель не в статусе `CONNECTED`. Ответ несёт `error.hint` с планом восстановления, см. ниже. Если пробуждение ЗАПРЕЩЕНО, приходит терминальный `409 GALAXY_HOST_WAKE_BLOCKED` — он `error.hint` не несёт |

Полный справочник общих ошибок API — [Ошибки](/docs/errors).

### Поле `error.hint` у `GALAXY_HOST_UNREACHABLE`

Ответ `502 GALAXY_HOST_UNREACHABLE` несёт объект `error.hint` из четырёх строк:

| Поле | Что содержит |
|------|--------------|
| `reason` | Почему галактика сейчас недоступна — её виртуальная машина просыпается либо агент переподключает туннель |
| `recovery` | Что делать. Текст зависит от того, откуда пришла ошибка — см. три ветки ниже |
| `recoveryAction` | Конкретное действие для повтора. Тоже зависит от источника ошибки |
| `note` | Оговорка: статус галактики в выдаче может отставать от реального состояния туннеля. Если состояние держится дольше 15 минут, галактика недоступна по-настоящему |

Поля `reason` и `note` одинаковы всегда, а `recovery` и `recoveryAction` различаются по источнику ошибки:

| Источник | Что советует подсказка |
|----------|------------------------|
| Загрузка кода (`POST /v1/infra/servers/:id/deploy`) | Подождать 1–2 минуты и повторить тот же деплой на тот же ID сервера. Спящая галактика будится самим деплоем автоматически |
| Выполнение команды (`POST /v1/infra/servers/:id/exec`) | **Важно:** если галактика спит, **повторы команду не разбудят** — сначала разбудите её деплоем или из кабинета, и только потом повторяйте. Если галактика работала, подождите 1–2 минуты, пока туннель переподключится |
| Удаление (`DELETE /v1/infra/servers/:id`) | Подождать 1–2 минуты и повторить удаление. Запись сервера сохраняется до того, как разбор действительно выполнится на галактике |

Во всех трёх случаях **удалять и пересоздавать приложение не нужно**: слот, его контейнер и том `/data` целы, а новый слот попадёт на ту же галактику и встретит то же состояние.

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

- [Создать сервер](./servers/create.md)
- [Полный деплой приложения](./deploy/deploy.md)
- [Логи сервера](./deploy/logs.md)
- [Удалить сервер](./servers/delete.md)
- [Инфраструктура](/docs/infra)
