Для AI-агентов: markdown этой страницы — /docs-content/infra/galaxy-sleep.md индекс документации — /llms.txt

Сон и пробуждение Galaxy-приложения

Galaxy-приложение засыпает по простою вместе с галактикой-носителем, и на время сна его контейнер остановлен. Эта страница описывает, что именно останавливается, какие поля показывают настоящее состояние, чем приложение поднять и сколько это занимает.

Что останавливается · Поля состояния · Чем поднять · Логи · Окно по расписанию

Что останавливается во сне

Приложение живёт в контейнере на общем хосте — галактике. Спать могут обе части, и это разные состояния.

Что спит Как это выглядит Что нужно, чтобы поднять
Что спитКонтейнер приложения, галактика работает Как это выглядитПриложение не отвечает, соседние приложения той же галактики работают Что нужно, чтобы поднятьЗапуск контейнера — секунды
Что спитГалактика вместе со всеми контейнерами Как это выглядитНе отвечает ни одно приложение этой галактики Что нужно, чтобы поднятьЗагрузка машины галактики, затем запуск контейнера — минуты

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

Поля status и reachability отвечают на разные вопросы

Поле status в ответе GET /v1/infra/servers/:id — это состояние учётной записи приложения на платформе. Пробуждение переводит запись в running в конце, когда контейнер уже запущен, поэтому во время подъёма галактики запись остаётся в sleeping — на холодной машине это занимает минуты. Обратное расхождение тоже возможно: запись может числиться в running, пока контейнер уже не работает.

Поэтому рядом идёт блок reachability — он отвечает на вопрос «может ли приложение ответить прямо сейчас». Блок приходит только у приложения, kind равен GALAXY_APP, у остальных типов серверов там null.

JSON
{
  "success": true,
  "data": {
    "id": "e22bb297-8a0a-4597-9b42-47d059cd1090",
    "kind": "GALAXY_APP",
    "status": "sleeping",
    "reachability": {
      "effectiveStatus": "running",
      "hostStatus": "running",
      "hostTunnel": "CONNECTED",
      "container": "running",
      "forwarder": "active",
      "publicEntry": "live",
      "probe": "ok",
      "probedAt": "2026-08-12T13:24:58.117Z"
    }
  }
}

Показаны поля, относящиеся к сну. Полный ответ — GET /v1/infra/servers/:id.

Поле Описание
ПолеeffectiveStatus ОписаниеСводный ответ о доступности — running, sleeping, waking, unreachable или unknown. Как он выводится, показано в таблице ниже
ПолеhostStatus ОписаниеСостояние галактики-носителя в том же наборе значений, что и status сервера
ПолеhostTunnel ОписаниеСоединение галактики с платформой — CONNECTED, DISCONNECTED или NONE
Полеcontainer ОписаниеКонтейнер приложения — running, stopped или unknown. Значение unknown означает, что платформа не смогла посмотреть, а не что контейнер остановлен
Полеforwarder ОписаниеМаршрутизация к контейнеру на хосте — active, inactive или unknown. Во сне останавливается вместе с контейнером
ПолеpublicEntry ОписаниеПубличный адрес приложения — live (у шлюза есть живой туннель на поддомен приложения), no-tunnel (туннеля нет, снаружи адрес не обслуживается) или unknown (спросить шлюз не удалось). Значение unknown вердикт никогда не ухудшает
Полеprobe ОписаниеЧем закончился живой опрос хоста — ok, host-down (галактика спит или недоступна, опрос не отправлялся), host-busy (хост занят другой операцией), failed или not-attempted
ПолеprobedAt ОписаниеВремя опроса по стандарту ISO 8601. Значение null означает, что опроса не было

Как складывается effectiveStatus:

Состояние effectiveStatus
СостояниеГалактика загружается effectiveStatuswaking
СостояниеГалактика спит effectiveStatussleeping
СостояниеГалактика работает, контейнер остановлен effectiveStatussleeping
СостояниеГалактика работает, контейнер работает, маршрутизация активна, у публичного адреса есть туннель effectiveStatusrunning
СостояниеГалактика работает, контейнер работает, маршрутизация активна, туннеля у публичного адреса нет effectiveStatusunreachable
СостояниеГалактика работает, контейнер работает, маршрутизация остановлена effectiveStatusunreachable
СостояниеГалактика в ошибке либо потеряла соединение с платформой effectiveStatusunreachable
СостояниеПосмотреть не удалось effectiveStatusunknown

Публичный вход проверяется отдельно. Контейнер и маршрутизация измеряются на самой галактике, а последний участок пути до https://app-XXXX.vibecode.bitrix24.tech — это туннель приложения на шлюзе, и на галактике его не видно: запущенный юнит маршрутизации означает, что его запустили, а не что он дозвонился до шлюза. Поэтому приложение с живым контейнером и активной маршрутизацией, но без туннеля, отвечает unreachable, а не running — снаружи такой адрес не обслуживается. Если состояние шлюза узнать не удалось, publicEntry равен unknown и вердикт остаётся прежним: «не смогли посмотреть» — это не «ничего не работает».

Важно: живой опрос хоста платформа делает только когда галактика работает и соединена с платформой. Спящую галактику чтение состояния не будит, поэтому у спящей галактики container и forwarder всегда unknown, а probe равен host-down. Результат опроса платформа держит несколько секунд и отдаёт из памяти: опрос занимает канал команд, общий для всех приложений галактики, поэтому частый опрос состояния его не занимает.

Чем поднять спящее приложение

Способ Что делает
СпособPOST /v1/infra/servers/:id/wake Что делаетПоднимает приложение через хост. При необходимости запускает галактику, затем стартует контейнер
СпособPOST /v1/infra/servers/:id/start Что делаетТо же самое. Отдельного смысла у двух вызовов для приложения нет
СпособЗагрузка кода Что делаетПоднимает галактику сама и оставляет приложение работающим
СпособОбращение к адресу приложения Что делаетЕсли пробуждение разрешено, запрос через шлюз поднимает приложение и до готовности отвечает кодом BH_SERVER_WAKING с заголовком Retry-After — подробности в Авторизации в приложении на Black Hole
СпособДоставка события портала Что делаетПлатформа поднимает приложение перед доставкой

Ответ на вызов пробуждения приходит сразу, а не по готовности: у приложения нет своей облачной машины, и параметр ?wait=true ожидания здесь не даёт. Готовность проверяйте опросом GET /v1/infra/servers/:id по полю reachability.effectiveStatus — значение waking означает, что галактика ещё загружается.

Сколько ждать: подъём холодной галактики платформа ждёт до 15 минут и столько же готова ждать от вызывающего. Точное значение бюджета приходит в ответе на чтение логов спящего приложения, поле recovery.coldBootBudgetSeconds. Приложение на уже работающей галактике стартует за секунды.

Запрет пробуждения на хосте блокирует оба вызова, и /start его не снимает. Коды отказов — в таблице жизненного цикла на странице Galaxy-приложение.

При обращении к адресу приложения без туннеля подтверждённый запрет пробуждения обрабатывается отдельно. Только в режиме PUBLIC шлюз возвращает 409 BH_APP_UNAVAILABLE без Retry-After: браузер показывает «Приложение временно недоступно» и кнопку «Обновить», машинный клиент получает JSON. Причина запрета, баланс и бренд платформы не раскрываются, пробуждение и автоматический опрос не запускаются. Уже открытая страница ожидания сменится этим экраном при следующем опросе. После снятия запрета повторите открытие вручную. В приватном режиме для опознанного пользователя сохраняется 402 BH_WAKE_BLOCKED.

Логи спящего приложения

Чтение GET /v1/infra/servers/:id/logs не будит ни приложение, ни галактику. Пока галактика спит или недоступна, ответ приходит со статусом 200, пустым массивом data.logs и двумя диагностическими полями.

JSON
{
  "success": true,
  "data": {
    "logs": [],
    "lines": [],
    "hint": "Galaxy host is asleep or unreachable, so the container log cannot be read right now. …",
    "recovery": {
      "reason": "The galaxy host carrying this container is not RUNNING + CONNECTED. …",
      "recoveryAction": "POST /v1/infra/servers/e22bb297-8a0a-4597-9b42-47d059cd1090/wake",
      "logsPreserved": true,
      "coldBootBudgetSeconds": 900,
      "poll": "GET /v1/infra/servers/e22bb297-8a0a-4597-9b42-47d059cd1090 (read `reachability`)",
      "wakeSchedule": { "available": true, "code": null }
    }
  }
}
Поле Описание
Полеhint ОписаниеТа же подсказка обычным текстом, одной строкой. Текст зависит от того, может ли вызывающий позвать пробуждение: когда может — называет вызов пробуждения; когда нет — адреса пробуждения не называет вовсе, зато называет ровно то условие, которое сработало именно у него. Второй путь подъёма подсказка называет только тогда, когда он этому вызывающему доступен, то есть вместе с полем recovery.deliveryWakesHost, а не всегда
Полеrecovery.reason ОписаниеПочему журнал сейчас не читается
Полеrecovery.recoveryAction ОписаниеВызов ПРОБУЖДЕНИЯ. Поле условное — его может не быть. Отсутствует всякий раз, когда вызывающий пробуждение позвать не может. Перечень таких состояний открыт и растёт, поэтому ветвитесь по НАЛИЧИЮ поля, а не по списку. Сегодня в него входят режим «только чтение», ключ Коворка/Кода, выключенный пилот галактик, ключ обслуживания агента, владелец с идущим удалением аккаунта и доступ к приложению по связи, когда сервером владеет другой ключ. Сюда же входит запрет пробуждения на самом ХОСТЕ галактики: он отбивает пробуждение любому вызывающему, включая полноправного владельца, поэтому в этом состоянии поля тоже нет. Проверяйте наличие ключа перед обращением: в этом состоянии адреса пробуждения нет ни в одном поле ответа — ни здесь, ни в hint. Важно: обратное не гарантия. НАЛИЧИЕ поля означает, что пробуждение не отбито ни по вызывающему, ни запретом на хосте, — но не что вызов состоится в любом случае: остаются отказы по СОСТОЯНИЮ пары, которые ответ логов не предсказывает (422, когда приложение не в том статусе или хост не загрузился, 404, когда галактика осиротела). Обрабатывайте такой отказ, а не считайте наличие поля гарантией
Полеrecovery.logsPreserved ОписаниеЗначение true означает, что строки, записанные до сна, доступны после пробуждения
Полеrecovery.coldBootBudgetSeconds ОписаниеБюджет подъёма холодной галактики в секундах
Полеrecovery.poll ОписаниеЧем проверять готовность вместо повторного чтения логов. Поле условное — его может не быть. Отсутствует, когда GET /v1/infra/servers/{id} отказывает самому вызывающему: у ключа обслуживания агента этого маршрута нет в перечне, а у владельца с идущим удалением аккаунта он живёт в замороженном контуре, в отличие от чтения журнала. Нет поля — просто перечитайте журнал позже, подсказка так и говорит
Полеrecovery.deliveryWakesHost ОписаниеВторой путь подъёма. Поле условное вдвойне: приходит, только когда пробуждение вызывающему недоступно И деплой ему при этом доступен. action — вызов деплоя, cost — его цена словами. Деплой на спящее галакси-приложение поднимает хост сам, но это ВЫКЛАДКА КОДА и расход баланса, а не пробуждение — ради одного лишь чтения журнала его звать не надо. Важно: отсутствие поля означает, что и этот путь закрыт: послабление режима «только чтение» снимает у деплоя гейт РЕЖИМА и только его, а ключу Коворка/Кода, выключенному пилоту и ключу обслуживания агента деплой отказывают те же двери, что и пробуждению. Поле отсутствует и при запрете пробуждения на хосте — деплой спящий хост с таким запретом НЕ поднимает, а отвечает 502
Полеrecovery.wakeSchedule ОписаниеДоступно ли окно пробуждения по расписанию этому вызывающему: и пригодность самого приложения, и право вызывающего на запись — одним вердиктом. Поле available — ответ, поле code при отказе несёт тот же код, которым ответит создание окна. Когда recoveryAction отсутствует, поле приходит available: false с кодом той двери, которая отбила пробуждение: создание окна — та же запись и отбивают её те же двери. Исключение — дверь окна, которая проверяется раньше этой: тогда code называет дверь окна, и hint называет ту же дверь, а не говорит, что окно отбивает то же условие, что и пробуждение. Важно: у окна есть и ДВЕ собственные двери, которых у пробуждения нет, поэтому code может назвать отказ, которого в списке дверей пробуждения не найти, а available: false может прийти и при наличии recoveryAction. Первая проверяется раньше всех остальных: маршрут окна отсутствует в перечне маршрутов ключа внешнего участника, тогда как пробуждение, деплой и чтение журнала в этом перечне есть, — EXTERNAL_COLLABORATOR_KEY_OUT_OF_SCOPE. Вторая проверяется позже дверей режима, заморозки, Коворка и пилота, но РАНЬШЕ проверки владения сервером: маршруту окна нужен скоуп vibe:infra, которого чтение логов и пробуждение не требуют, поэтому до этого отказа доходит и обычный ключ без скоупа — INFRA_SCOPE_REQUIRED, и лечится он выдачей скоупа, а не сменой режима. Владение проверяется после скоупа, поэтому вызывающему, пришедшему по связи приложения и не несущему скоуп, придёт INFRA_SCOPE_REQUIRED, а не NOT_FOUND

Порядок действий: поднять приложение вызовом из recovery.recoveryAction, дождаться reachability.effectiveStatus равного running, повторить чтение логов.

Если поля recoveryAction в ответе нет — пробуждение откажут. Причина бывает двух родов, и hint называет ту, что сработала: либо дверь самого вызывающего (перечень ниже), либо запрет пробуждения на ХОСТЕ галактики — тогда ключ ни при чём, отказ придёт любому, и снимать запрет идёт владелец аккаунта. Вызов пробуждения в этом состоянии отвечает 403 SERVER_WAKE_BLOCKED, а пока у аккаунта просрочен доступ — 402 с кодом подписочной или тарифной стены. Окно по расписанию в этом состоянии создать можно, но хост оно не поднимет: запрет действует и на пробуждение по расписанию. Адреса пробуждения нет и в прозе: в этом состоянии ответ намеренно не называет ни POST …/wake, ни создание окна по расписанию — окно отбивает та же дверь. hint вместо адреса называет ровно то условие, которое сработало у него самого, а не список через «или», — и называет ПЕРВОЕ по порядку, в каком двери отбивают на самом деле. Порядок такой: у ключа обслуживания агента пробуждения нет в перечне маршрутов; при идущем удалении аккаунта пробуждение закрыто целиком, и смена ключа не поможет — заморожен владелец, а не ключ (доставка при этом остаётся открытой, см. ниже про второй путь); режим ключа переключается по Режиму доступа; ключу Коворка/Кода управляющий контур закрыт целиком; выключенный пилот галактик снимает администратор аккаунта; и последняя — доступ к приложению по связи, когда сервером владеет другой ключ: пробуждение проверяет владение строже, чем чтение журнала, поэтому такому вызывающему оно отвечает 404, и помогает только вызов ключом-владельцем сервера.

У части вызывающих выход всё же есть, и это не пробуждение. Ключу в режиме «только чтение» разрешён деплой на свой сервер, а деплой на спящее галакси-приложение поднимает хост сам. Тот же путь открыт ещё двум вызывающим, которым отказано в пробуждении: владельцу с идущим удалением аккаунта (заморозка стоит на плагине /v1/infra, а доставка живёт в другом) и тому, кого пустили по связи приложения (владение доставка проверяет мягче, чем пробуждение). Закрыт этот путь ровно трём: ключу Коворка/Кода, ключу обслуживания агента и вызывающему на аккаунте с выключенным пилотом галактик. Когда этот путь открыт, платформа называет его машинно — полем recovery.deliveryWakesHost (action — вызов, cost — цена словами), и цена тут не формальность: это выкладка кода и расход баланса Вайбкод, а не пробуждение. Звать его ради одного лишь чтения журнала не надо.

Открыт он не всем, и поле это показывает. Послабление для режима «только чтение» снимает у деплоя гейт РЕЖИМА и только его. Ключу Коворка/Кода управляющий контур закрыт целиком, при выключенном пилоте галактик отказывают любые не-GET по этому семейству, а у ключа обслуживания агента деплоя нет в его перечне маршрутов — всем троим POST …/deploy ответит отказом ровно так же, как и пробуждение. Поэтому проверяйте наличие deliveryWakesHost, а не предполагайте его: нет поля — открытого пути нет, и надо менять условие из hint. Важно: обратное тоже не гарантировано, ровно как у recoveryAction: наличие поля означает, что деплой не отбит ни по identity и режиму ключа, ни запретом на хосте. Оно не отвечает за состояние счёта НА МОМЕНТ ВЫЗОВА: заморозка баланса закрывает всё семейство /v1/infra целиком (402 ACCOUNT_FROZEN), и если она наступит после этого чтения, названный action получит именно её — тем более что деплой тратит баланс по построению. Пока условие не изменилось, повторять чтение логов в цикле смысла нет: ответ не изменится.

Окно пробуждения по расписанию

Окно пробуждения поднимает приложение по расписанию, без вызова руками. Доступно оно не каждому приложению, и проверять это следует по ответу платформы, а не по общему правилу: поле recovery.wakeSchedule в ответе на чтение логов спящего приложения даёт готовый ответ для конкретного приложения, а при отказе — его код.

Ответ этот — и про приложение, и про вызывающего сразу. Создание окна остаётся записью, поэтому ключу в режиме «только чтение», ключу Коворка/Кода и порталу с выключенным пилотом галактик оно откажет; в этих состояниях поле приходит available: false с кодом отбившей двери. Пробуждение — хороший первый признак: нет recovery.recoveryAction — окна этому вызывающему тоже не создать. Но признак этот не полный, потому что у окна есть две двери, которых у пробуждения нет: маршрут отсутствует в перечне ключа внешнего участника (EXTERNAL_COLLABORATOR_KEY_OUT_OF_SCOPE) и требует скоуп vibe:infra, которого пробуждение не требует (INFRA_SCOPE_REQUIRED). Любая из двух откажет в окне и тому, кто приложение разбудить может, — поэтому читайте само поле recovery.wakeSchedule, а не выводите его из recoveryAction.

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

Список окон, создание, изменение и удаление — Пробуждение по расписанию.

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