Qadam Roadmap
проектdocs/operations/verification-server-bootstrap.md

Runbook поднятия отдельного проверочного сервера

Обновлён 1 апр. 2026 г., 12:41 · 0 комментариев

Runbook поднятия отдельного проверочного сервера

Паспорт документа

  • Статус документа: working reference
  • Актуально на: 1 апреля 2026 года
  • Владелец: backend/platform-команда
  • Пересмотр: при изменении deploy-контура qadam-core, qadam-web, env-модели или схемы staging/bootstrap сервера
  • Область применения: быстрый и воспроизводимый подъём отдельного сервера, на котором одновременно работают backend и product web для UI-проверок
  • Связанные документы:

Цель документа

Этот документ нужен для случая, когда проект надо быстро поднять на отдельном сервере так, чтобы:

  • backend и frontend работали вместе;
  • UI можно было проверять в браузере как единый продукт;
  • сборка и запуск не зависели от устного контекста;
  • было ясно, что берётся из Git, а что надо переносить отдельно как runtime-конфигурацию.

1. Краткий вывод по готовности

На 1 апреля 2026 года проект уже можно забирать с Git на отдельный сервер.

Фактически подтверждено:

  • qadam-core в рабочем дереве чистый и запушен в origin/main;
  • qadam-web в рабочем дереве чистый и запушен в origin/main;
  • в qadam-core уже лежат канонические Docker/compose/runtime-артефакты для api;
  • в qadam-web уже лежат канонические Docker/compose/runtime-артефакты для product web;
  • оба репозитория уже рассматриваются как source of truth вместо legacy checkout.

Проверенные HEAD на момент составления этого runbook:

  • qadam-core: a0bd363
  • qadam-web: 5af095d

Важно: из Git забирается не весь runtime-контур. Вне Git всё ещё остаются:

  • production/stage secrets;
  • env-файлы;
  • nginx-конфигурация;
  • TLS;
  • живая PostgreSQL/Redis инфраструктура;
  • object storage credentials;
  • любые данные БД и загруженные product media.

Итог:

  • код и deploy-артефакты можно брать из Git уже сейчас;
  • новый сервер нельзя считать полностью самоподнимаемым только после git clone, пока не подготовлены env, домен и инфраструктурные зависимости.

2. Что рекомендуется поднимать на новом сервере

Для отдельного проверочного сервера рекомендуется такой минимальный контур:

  • один публичный stage-домен, например stage-qadam.example.com;
  • один nginx, который проксирует:
    • /api/* на backend;
    • /* на product web;
  • PostgreSQL и Redis на этом же сервере или как внешние managed сервисы;
  • qadam-core/api как container runtime;
  • qadam-web как container runtime;
  • qadam-roadmap на этом сервере не обязателен, если цель именно UI-проверка продукта.

Почему именно так:

  • одна origin-схема упрощает cookie auth;
  • backend уже лучше всего подготовлен к контейнерному запуску;
  • product web уже имеет registry/build/smoke baseline и может быть поднят рядом;
  • для UI-проверок не нужен отдельный docs-service, если нет задачи тестировать сам roadmap.

3. Что обязательно должно быть вне Git

Инфраструктурные зависимости

  • PostgreSQL
  • Redis
  • домен или хотя бы публичный IP
  • nginx
  • Docker Engine и docker compose
  • Node.js 20+
  • pnpm 9.15.4+

Секреты и runtime env

Минимально нужны:

  • DATABASE_URL
  • REDIS_URL
  • JWT_SECRET
  • CORS_ORIGIN
  • NEXT_PUBLIC_API_URL
  • API_URL
  • OBJECT_STORAGE_DRIVER
  • S3_*, если stage должен работать с реальным object storage

Опционально:

  • AXIOM_*
  • TELEGRAM_*
  • backup/monitoring env

Полный состав и границы ownership описаны в environment-matrix.md.

4. Рекомендуемая схема каталогов на новом сервере

/srv/qadam-core
/srv/qadam-web
/etc/qadam/qadam.env
/etc/qadam/qadam-api-runtime.env
/etc/qadam/qadam-web-runtime.env

Если на сервере есть отдельный большой диск под Docker/build cache, его надо использовать как data-root, а не корневой раздел.

5. Порядок развертывания

Шаг 1. Подготовить сервер

Нужны:

  • git
  • curl
  • docker
  • docker compose
  • node
  • pnpm
  • nginx
  • postgresql-client

Если PostgreSQL и Redis локальные, они тоже должны быть установлены и доступны.

Шаг 2. Клонировать репозитории

git clone https://git.2fab.app/eldar/qadam-core.git /srv/qadam-core
git clone https://git.2fab.app/eldar/qadam-web.git /srv/qadam-web

Для воспроизводимого поднятия лучше сразу фиксировать commit SHA:

git -C /srv/qadam-core checkout <core-sha>
git -C /srv/qadam-web checkout <web-sha>

Шаг 3. Подготовить env-файлы

/etc/qadam/qadam.env

Это основной runtime env для backend.

Минимальный шаблон:

NODE_ENV=production
PORT=5002
HOSTNAME=127.0.0.1

DATABASE_URL=postgresql://...
REDIS_URL=redis://127.0.0.1:6379
JWT_SECRET=...

CORS_ORIGIN=https://stage-qadam.example.com
PUBLIC_WEB_BASE_URL=https://stage-qadam.example.com

OBJECT_STORAGE_DRIVER=s3
S3_ENDPOINT=...
S3_REGION=...
S3_BUCKET=...
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_PUBLIC_BASE_URL=...
S3_FORCE_PATH_STYLE=false
S3_OBJECT_ACL=public-read

/etc/qadam/qadam-api-runtime.env

QADAM_API_IMAGE=qadam-core-api:git-<commit-sha>
QADAM_API_ENV_FILE=/etc/qadam/qadam.env
QADAM_API_PORT=5002
QADAM_API_HOSTNAME=127.0.0.1
QADAM_API_COMPOSE_PROJECT=qadam-api-stage

/etc/qadam/qadam-web-runtime.env

NODE_ENV=production
API_URL=http://host.docker.internal:5002/api/v1
NEXT_PUBLIC_API_URL=https://stage-qadam.example.com/api/v1

Если домен ещё не настроен и тест идёт по IP, временно допустимо:

NEXT_PUBLIC_API_URL=http://<SERVER_IP>/api/v1

Но для cookie auth и итоговой UI-проверки лучше сразу использовать один stage-домен.

Шаг 4. Поднять backend

cd /srv/qadam-core
pnpm install --frozen-lockfile
pnpm check-types
pnpm test
pnpm build
pnpm export:openapi
pnpm docker:build:api

Применить миграции:

cd /srv/qadam-core
set -a
source /etc/qadam/qadam-api-runtime.env
set +a

docker compose \
  -f deploy/compose/docker-compose.api-runtime.yml \
  --project-name "${QADAM_API_COMPOSE_PROJECT}" \
  --profile ops \
  run --rm migrate

Если БД новая и нужен базовый справочный контур:

cd /srv/qadam-core
set -a
source /etc/qadam/qadam-api-runtime.env
set +a

docker compose \
  -f deploy/compose/docker-compose.api-runtime.yml \
  --project-name "${QADAM_API_COMPOSE_PROJECT}" \
  --profile ops \
  run --rm seed

Поднять API runtime:

cd /srv/qadam-core
set -a
source /etc/qadam/qadam-api-runtime.env
set +a

docker compose \
  -f deploy/compose/docker-compose.api-runtime.yml \
  --project-name "${QADAM_API_COMPOSE_PROJECT}" \
  up -d api

Проверка:

curl -fsS http://127.0.0.1:5002/api/v1/health/live
curl -fsS http://127.0.0.1:5002/api/v1/health/ready

Шаг 5. Синхронизировать OpenAPI и поднять frontend

Сначала синхронизировать frontend с текущим backend artifact:

cp /srv/qadam-core/apps/api/openapi/openapi.json /srv/qadam-web/openapi/openapi.json

Затем собрать web:

cd /srv/qadam-web
pnpm install --frozen-lockfile
pnpm generate:api-contract
pnpm check-types
pnpm build
pnpm docker:build:web

Поднять web runtime:

cd /srv/qadam-web
QADAM_WEB_IMAGE=qadam-web:git-$(git rev-parse --short=12 HEAD) \
QADAM_WEB_ENV_FILE=/etc/qadam/qadam-web-runtime.env \
QADAM_WEB_PORT=3002 \
QADAM_WEB_BIND_HOST=127.0.0.1 \
QADAM_WEB_COMPOSE_PROJECT=qadam-web-stage \
docker compose \
  -f deploy/compose/docker-compose.web-runtime.yml \
  --project-name qadam-web-stage \
  up -d web

Проверка:

curl -fsS http://127.0.0.1:3002/api/health
curl -I http://127.0.0.1:3002

6. Минимальный nginx для одного stage-домена

Идея простая:

  • /api/ уходит на 127.0.0.1:5002
  • / уходит на 127.0.0.1:3002

Минимальный контур:

server {
    listen 80;
    server_name stage-qadam.example.com;

    location /api/ {
        proxy_pass http://127.0.0.1:5002;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location / {
        proxy_pass http://127.0.0.1:3002;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

После этого уже можно навешивать TLS через certbot.

7. Smoke checklist после поднятия

Backend

curl -fsS http://127.0.0.1:5002/api/v1/health/live
curl -fsS http://127.0.0.1:5002/api/v1/health/ready
curl -I http://127.0.0.1:5002/api/docs

Frontend

curl -I http://127.0.0.1:3002
curl -fsS http://127.0.0.1:3002/api/health

Через публичный домен

curl -I https://stage-qadam.example.com
curl -I https://stage-qadam.example.com/api/docs
curl -fsS https://stage-qadam.example.com/api/v1/health/ready

UI-проверка в браузере

Минимально проверить:

  • открывается главная страница;
  • грузятся CSS и JS чанки;
  • работает login/register flow хотя бы до transport-слоя;
  • seller/public pages не падают на SSR;
  • /api/docs доступен и совпадает с ожидаемым backend-контрактом.

8. Что уже готово в Git, а что ещё не полностью упаковано

Уже готово

  • qadam-core: код, Dockerfile, compose runtime, build/publish/smoke scripts
  • qadam-web: код, Dockerfile, compose runtime, build/publish/smoke scripts
  • OpenAPI artifact и contract workflow
  • Prisma migrations и seed baseline
  • документация по env и deploy-контуру

Ещё не полностью упаковано в Git как turnkey bootstrap

  • готовые nginx vhost-файлы для нового stage-домена;
  • готовые systemd units именно для нового stage-контура qadam-web;
  • секреты и runtime env;
  • dump/данные БД для предметного UI-теста с наполнением;
  • roadmap runtime, если нужно тащить и его.

Это не блокирует подъём нового сервера, но означает, что staging всё ещё требует осознанного инфраструктурного шага, а не только git clone.

9. Канонический вывод

Если задача — быстро поднять отдельный сервер, на котором backend и frontend уже можно проверять вместе в браузере, проект к этому готов.

Самый короткий практический путь сейчас такой:

  1. взять оба репозитория из Git;
  2. подготовить env и инфраструктурные зависимости;
  3. поднять api на 127.0.0.1:5002;
  4. поднять web на 127.0.0.1:3002;
  5. свести их под один stage-домен через nginx.

Для этой задачи текущий Git-контур уже достаточен. Не хватает не кода, а только stage-specific runtime-конфигурации и секретов.