Быстрый цикл редеплоя

🚀 Сложность: medium | Скоупы: vibe:infra | Стек: cURL

Полный редеплой через `POST /v1/infra/servers/:id/deploy` прогоняет девять шагов подряд: остановка сервиса, очистка, скачивание архива, установка рантайма, установка зависимостей, запись .env, команды preStart, создание systemd-юнита, запуск и проверка работоспособности. Спящий сервер деплой будит сам. Это правильный путь для первого выпуска и для смены рантайма, но на каждой мелкой правке кода прогонять все девять шагов долго. Ниже — четыре приёма, которые сокращают цикл: убрать раздувание тела запроса, не переустанавливать тяжёлые зависимости, обновлять один изменившийся файл вместо всего дерева, держать данные отдельно от кода.

Во всех примерах $VIBE_URL — базовый адрес https://vibecode.bitrix24.tech, $SERVER_ID — идентификатор BLACKHOLE-сервера, $VIBE_API_KEY — API-ключ Вайбкод со скоупом vibe:infra.

Multipart вместо base64

Встроенный source.content — это base64-строка архива, а base64 увеличивает объём примерно на 33 %: архив 30 МБ уходит по проводу как 40 МБ. Multipart-режим передаёт архив файлом-как-есть, без этой надбавки. Второе отличие — cleanDeploy в multipart-режиме по умолчанию "false" (merge-деплой: новые файлы кладутся поверх существующего дерева), тогда как inline-деплой из JSON по умолчанию cleanDeploy: true и стирает /opt/app перед распаковкой. Для итеративной правки merge-режим быстрее — не нужно каждый раз выкладывать полное дерево.

Terminal
tar -czf app.tar.gz -C ./my-app .
curl -sS -X POST "$VIBE_URL/v1/infra/servers/$SERVER_ID/deploy" \
  -H "X-Api-Key: $VIBE_API_KEY" \
  -F "archive=@app.tar.gz" \
  -F "start=cd /opt/app && node server.js" \
  -F "port=3000"

Порт в multipart-режиме передавать обязательно — строкой ("3000"). Чтобы вместо merge сделать чистый деплой, добавьте -F "cleanDeploy=true".

Тяжёлые зависимости — вне install-скрипта

У шага install таймаут 300 секунд, и запускается он на каждом деплое. Долгая установка набора инструментов сборки на этом шаге либо упирается в таймаут, либо отнимает минуты у каждого деплоя. Файловая система виртуальной машины помогает этого избежать: cleanDeploy стирает только extractTo (по умолчанию /opt/app), а установленные рантаймы, каталог /usr и /opt/data переживают редеплой. Поэтому системный инструмент ставится один раз и остаётся на месте.

Установите тяжёлый инструмент однажды и в дальнейшем проверяйте его наличие идемпотентной строкой — она запускает установочный скрипт, только если инструмента ещё нет:

Terminal
command -v pg_restore >/dev/null || bash /opt/data/install-tools.sh

Строку помещают в preStart. При первом деплое pg_restore не найден — скрипт отработает. На следующих деплоях инструмент уже на месте, проверка проходит мгновенно, установка не повторяется. Так каждый деплой не платит за переустановку того, что уже стоит на диске.

Точечные обновления через /upload

Когда изменился один файл или один бандл, полный редеплой избыточен. Загрузите изменившийся архив через `POST /v1/infra/servers/:id/upload` с extract: true — агент распакует его прямо в рабочую директорию, минуя остальные восемь шагов деплоя. Затем перезапустите сервис через `/exec`:

Terminal
curl -sS -X POST "$VIBE_URL/v1/infra/servers/$SERVER_ID/upload" \
  -H "X-Api-Key: $VIBE_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/dist.tar.gz",
    "path": "/opt/app/dist.tar.gz",
    "extract": true,
    "extractTo": "/opt/app"
  }'

curl -sS -X POST "$VIBE_URL/v1/infra/servers/$SERVER_ID/exec" \
  -H "X-Api-Key: $VIBE_API_KEY" -H "Content-Type: application/json" \
  -d '{"command": "systemctl restart app"}'

Имя сервиса в команде перезапуска — то, под которым приложение задеплоено. По умолчанию это app, поэтому и systemctl restart app. Загрузка размером до 500 МБ — с ней проходит и целый бандл, и отдельный файл.

Данные — никогда в install-шаге

Шаг installpreStart) выполняется на каждом деплое. Если положить в него загрузку данных — вставку строк в базу, импорт справочника, накат начальных данных — эта загрузка повторится при каждом деплое, и записи задвоятся. Данные грузят в /opt/data один раз и под идемпотентной защитой, чтобы повторный запуск ничего не добавлял:

Terminal
test -f /opt/data/.seeded || { bash /opt/data/load-seed.sh && touch /opt/data/.seeded; }

Каталог /opt/data переживает редеплой, поэтому файл-маркер .seeded остаётся на месте между деплоями. Первый деплой загрузит данные и поставит маркер, все следующие увидят маркер и пропустят загрузку. Команды-шаги деплоя держите для установки кода и зависимостей, а разовую загрузку данных выносите под такую защиту.

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