## Подготовить хост

`POST /v1/infra/servers/:id/app-db/prepare`

Запускает подготовку хоста галактики для работы с базой приложения: ставит недостающие пакеты и служебный образ для чтения базы. Подготовка идёт в фоне, её ход показывает статус подготовки хоста.

## Параметры

| Параметр | Тип | Обяз. | Описание |
|----------|-----|:-----:|----------|
| `id` (path) | string (UUID) | да | ID приложения с `kind` равным `GALAXY_APP`. Список: [`GET /v1/infra/servers`](/docs/infra/servers/list) |

Тело запроса может быть пустым или `{}`, не больше 4096 байт. Любое поле тела и любой параметр строки запроса отклоняются с `400 VALIDATION_ERROR`.

## Примеры

### curl — личный ключ

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/APP_ID/app-db/prepare" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

### curl — OAuth-приложение

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/APP_ID/app-db/prepare" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

### JavaScript — личный ключ

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${appId}/app-db/prepare`,
  {
    method: 'POST',
    headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
    body: '{}',
  }
)
const { success, data, error } = await res.json()
if (!success) throw new Error(error.code)
// 202 — подготовка идёт, опрашивайте GET по тому же адресу. 200 — хост уже готов
console.log(res.status, data.state)
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${appId}/app-db/prepare`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: '{}',
  }
)
const { success, data, error } = await res.json()
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | `true`, если подготовка запущена, уже идёт или не нужна |
| `data.state` | string | `preparing` — подготовка запущена этим вызовом или уже шла, HTTP `202`. `ready` — хост уже готов, HTTP `200` |
| `data.steps` | array | Семь шагов в фиксированном порядке: `disk`, `python3`, `zstd`, `age`, `curl`, `image`, `verify` |
| `data.steps[].id` | string | Шаг. Значения — в [статусе подготовки](/docs/infra/database/prepare-status) |
| `data.steps[].state` | string | `pending`, `running`, `done`, `present` или `failed`. В ответе на запуск компоненты, которые уже есть на хосте, отмечены `present`, остальные шаги — `pending` |
| `data.missing` | string[] | Компоненты, которых нет на хосте: `python3`, `zstd`, `age`, `curl`, `image`. При `ready` массив пуст |
| `data.freeBytes` | integer | Меньшее из свободного места на корневом разделе и на разделе образов Docker, в байтах. Приходит, когда подготовка уже шла и замер был |

## Пример ответа

Подготовка запущена, HTTP `202`:

```json
{
  "success": true,
  "data": {
    "state": "preparing",
    "missing": ["image"],
    "steps": [
      { "id": "disk", "state": "pending" },
      { "id": "python3", "state": "present" },
      { "id": "zstd", "state": "present" },
      { "id": "age", "state": "present" },
      { "id": "curl", "state": "present" },
      { "id": "image", "state": "pending" },
      { "id": "verify", "state": "pending" }
    ]
  }
}
```

Хост уже готов, HTTP `200`:

```json
{
  "success": true,
  "data": {
    "state": "ready",
    "steps": [
      { "id": "disk", "state": "done" },
      { "id": "python3", "state": "present" },
      { "id": "zstd", "state": "present" },
      { "id": "age", "state": "present" },
      { "id": "curl", "state": "present" },
      { "id": "image", "state": "present" },
      { "id": "verify", "state": "done" }
    ],
    "missing": []
  }
}
```

## Пример ответа при ошибке

400 — в теле передано поле:

```json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid preparation parameters"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | В теле есть поле, или передан параметр строки запроса |
| 400 | `APP_DB_UNSUPPORTED_PLACEMENT` | Приложение размещено не в Галактике |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Ключ не опознан |
| 402 | `BILLING_FROZEN` | Счёт портала заморожен |
| 403 | `INFRA_SCOPE_REQUIRED` | У ключа нет скоупа `vibe:infra` |
| 403 | `APP_DB_DISABLED` | Работа с базой приложения не включена для портала |
| 403 | `APP_DB_READONLY_KEY` | Ключ в режиме только чтения |
| 403 | `SERVER_WAKE_BLOCKED` | Хост галактики спит, а его пробуждение запрещено |
| 404 | `NOT_FOUND` | Приложение или его хост не найдены, удалены или недоступны этому ключу |
| 409 | `APP_DB_BUSY` | Хост не успел проснуться за 10 секунд или занят другой операцией. Повторите после паузы из `Retry-After` |
| 413 | `PAYLOAD_TOO_LARGE` | Тело больше 4096 байт |
| 429 | `RATE_LIMITED` | Превышен лимит запросов на запись для портала — [Лимиты](/docs/infra/database#лимиты). Пауза — в заголовке `Retry-After` |
| 503 | `APP_DB_TOOL_UNAVAILABLE` | Служебный канал к хосту недоступен, или хост вернул некорректное состояние. Повторите после паузы из `Retry-After` |
| 503 | `user_self_deletion_pending` | Владелец ключа удаляет свой аккаунт на портале |

Причина неудачи самой подготовки приходит не ошибкой этого вызова, а в состоянии `failed` с `data.errorCode` в [статусе подготовки](/docs/infra/database/prepare-status).

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

## Известные особенности

- **Что ставится на хост.** Только отсутствующие `python3`, `zstd`, `age`, `curl` и закреплённый служебный образ для чтения базы. Пакеты ставятся из настроенных на хосте репозиториев Ubuntu с проверкой подписи. План установки проверяется перед каждым пакетом: обновлять и удалять уже установленные пакеты запрещено. Пакеты не запускают и не перезапускают службы, хост не перезагружается, приложение и Docker не перезапускаются. Нужно не меньше 6 ГиБ свободного места на корневом разделе и на разделе образов Docker. Подготовка ограничена 15 минутами.
- **Подготовку выполняет платформа.** Команды идут к хосту через служебный канал платформы. Ни вам, ни приложению доступ к хосту для этого не нужен.
- **Повторный вызов.** Пока подготовка идёт, вызов ничего не запускает и возвращает текущее состояние с HTTP `202`. После `failed` вызов запускает подготовку заново, уже установленные компоненты пропускаются. Если ответ на запуск потерялся, сначала проверьте [статус подготовки](/docs/infra/database/prepare-status), а не повторяйте запуск автоматически.
- **Подготовка запускается и без этого вызова.** Новый хост галактики запускает её сам при первой загрузке. Создание копии базы — ручной, ежедневной или защитной — тоже запускает подготовку на неготовом хосте, если прошлая подготовка не закончилась кодом `LOW_DISK`, `DPKG_BROKEN`, `APT_PLAN_UNSAFE` или `UNSUPPORTED_HOST`. Этот вызов запускает её и после таких кодов.
- **Длительность.** На тестовом хосте, где пакеты уже стояли и загружался только служебный образ, подготовка заняла меньше 10 секунд.

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

- [Получить статус подготовки хоста](/docs/infra/database/prepare-status)
- [Получить сведения о базе](/docs/infra/database/info)
- [Создать копию базы](/docs/infra/database/snapshot)
- [База данных приложения](/docs/infra/database)
