Единый dev stand
Единый dev stand - это локальный Docker Compose стенд для ручной и автоматизированной full-stack QA. Он поднимает Mini Shop, PostgreSQL, Redis, локальную Remnawave Panel, Remnawave Subscription Page и сиды для тестовых пользователей.
Канонический короткий вход из корня репозитория:
make dev применяет latest-пресет 2.8.1, валидирует compose-конфиг и поднимает стенд.
Для другого пресета используйте $env:DEV_PRESET = "2.8.0"; make dev. Эквивалентные npm-команды:
Старые compose-файлы не являются отдельными dev stand:
docker-compose-dev.yml- базовый локальный Mini Shop стек.docker-compose.remnawave-dev.yml- overlay с Remnawave, Subscription Page и dev-сидами. Именно вместе с базовым файлом он образует единый dev stand.docker-compose.test.yml- изолированный runner для backend test suite.docker-compose.demo.yml- nginx для статической docs-demo.docker-compose.yml- production-like запуск приложения, не QA-стенд.
Пинованные версии latest-пресета, проверенные 2026-07-16:
- Remnawave Panel
v2.8.1(remnawave/backend:2.8.1) - Remnawave Node
v2.8.0(remnawave/node:2.8.0) - Remnawave Subscription Page
7.2.6(remnawave/subscription-page:7.2.6)
Текущий автоматический dev stand поднимает локальную Panel и Subscription Page.
Отдельная Remnawave Node не стартует без регистрации ноды в панели и SECRET_KEY;
REMNAWAVE_NODE_VERSION фиксирует версию для локальной node-части стенда, если она
поднимается отдельно.
Чтобы вручную проверить другую связку Remnawave, поменяйте в .env.remnawave-dev:
Эти же версии зафиксированы в deploy/dev/remnawave-versions.lock.json.
Full-stack QA проверяет, что env example и lock-файл не разъехались.
Версионные пресеты
Заголовок раздела «Версионные пресеты»Для проверки совместимости не копируйте весь compose-файл в папку версии. Dev stand использует
один overlay docker-compose.remnawave-dev.yml, а версии и локальные volume names задаются
маленькими пресетами в deploy/dev/remnawave-stands/<panel-version>/:
stand.env- теги Panel, Node, Subscription Page и version-specific volumes.versions.lock.json- machine-readable lock для тестов и ревью.
Сейчас поддерживаются три пресета:
2.8.1: Panel2.8.1, Node2.8.0, Subscription Page7.2.6.2.8.0: Panel2.8.0, Node2.8.0, Subscription Page7.2.6.2.7.4: Panel2.7.4, Node2.7.0, Subscription Page7.2.4.
Переключение на previous compatibility preset:
Возврат на latest:
Пресеты используют разные Docker volumes (*-274, *-280, *-281), чтобы миграции разных
версий панели не портили соседние базы. Одновременно эти стенды не запускаются: у compose остаются
фиксированные container names и локальные порты. Если когда-нибудь понадобится параллельный запуск,
тогда нужно будет параметризовать еще project name, container names и ports, но сейчас это лишний
операционный вес.
Политика поддержки: держим latest-пресет и один предыдущий совместимый пресет, пока реально поддерживаем upgrade path. Более старые версии добавляем только если релиз панели меняет API, webhook-контракты или схему данных так, что без отдельной регрессии высокий риск. Неактуальные пресеты можно удалять после явного решения, когда они больше не проверяются и не нужны пользователям.
Переменные окружения
Заголовок раздела «Переменные окружения»Файл deploy/dev/remnawave-dev.env.example уже содержит локальные безопасные
значения. Скопируйте его в .env.remnawave-dev и меняйте только локально:
По умолчанию Mini Shop работает в dry-run режиме записи в панель:
Это удобно для QA: приложение читает живую локальную Remnawave Panel, но опасные мутации можно прогонять без реального изменения panel-состояния. Если нужен live-режим против локальной панели, замените токен на токен из Remnawave Settings -> API Tokens и включите:
Детерминированный REMNAWAVE_DEV_API_TOKEN из example сидируется SQL-файлом
deploy/dev/seed-remnawave.sql. Не меняйте
REMNAWAVE_DEV_APP_SECRET, если не заменяете этот токен. Overlay передаёт его панели как
APP_SECRET и как legacy JWT_AUTH_SECRET, чтобы те же пресеты работали с Panel 2.8.1 и 2.8.0.
Для автоматизированной QA в example включены только dev/test-safe хуки:
QA_AUTH_ENABLED возвращает одноразовый email-код в ответе
/api/auth/email/request, но только в APP_RUNTIME_MODE=development|test.
QA_PAYMENT_ENABLED включает локальный provider qa; его webhook принимает
только HMAC-подписанные payload через X-QA-Payment-Signature.
Логи основных сервисов:
Full-stack QA поверх поднятого стенда:
Без QA_FULLSTACK=1 tests/qa пропускаются, чтобы обычный pytest не
зависел от Docker Compose.
Остановка без удаления БД:
Чтобы удалить локальные базы и сиды, выполните тот же compose down -v
вручную:
- Mini Shop frontend:
http://127.0.0.1:8082 - Mini Shop backend health:
http://127.0.0.1:8080/healthz - Mini Shop PostgreSQL:
127.0.0.1:6768 - Remnawave Panel:
http://127.0.0.1:3000 - Remnawave metrics health:
http://127.0.0.1:3001/health - Remnawave Subscription Page upstream:
http://127.0.0.1:3010
Subscription Page требует reverse proxy с HTTPS для прямого браузерного
использования. В этом стенде 127.0.0.1:3010 - локальный upstream; plain HTTP
запрос может вернуть empty reply, даже если сервис здоров и подключен к
Remnawave Panel.
Профиль seed выполняет два идемпотентных SQL-файла:
deploy/dev/seed-minishop.sql- пользователи, подписки и платежи Mini Shop.deploy/dev/seed-remnawave.sql- API token, пользователи Remnawave и привязка кDefault-Squad.
Тестовые пользователи:
| Telegram/user ID | Состояние | HWID devices | |
|---|---|---|---|
910000001 |
runes.admin@example.com |
активная standard-подписка, admin ID | 2 из 3 |
910000002 |
runes.active@example.com |
активная premium-подписка около лимита трафика | 3 из 5 |
910000003 |
runes.expired@example.com |
истекшая подписка | 1 из 1 |
Повторный запуск сидов:
Overlay использует version-specific volumes из выбранного пресета, например
remnawave-minishop-runes-dev-db-data-280 и
remnawave-minishop-runes-dev-redis-data-280, чтобы не портить старый локальный
dev-стек и не смешивать базы разных версий Remnawave.
Smoke-проверка стенда
Заголовок раздела «Smoke-проверка стенда»Автоматизация реальных QA-сценариев
Заголовок раздела «Автоматизация реальных QA-сценариев»Реальный QA-слой находится в tests/qa и запускается командой
npm run qa:fullstack поверх единого dev stand. Он покрывает сценарии, которые
не должен был покрывать mock-smoke из runes-плана: mock-smoke проверяет
статическую demo-сборку без backend, а full-stack QA проверяет живые auth,
CSRF, платежный webhook, admin-save и состояние БД.
Текущие сценарии:
- Email auth через
/api/auth/email/requestи/api/auth/email/verify. - CSRF-protected пользовательский запрос
/api/account/language. - Создание платежа через
/api/paymentsс providerqa. - HMAC webhook
/webhook/qa-paymentи настоящийfinalize_successful_paymentс активацией подписки. - Проверка
paymentsиsubscriptionsв PostgreSQL после webhook. - Admin login и сохранение
SERVER_STATUS_URLчерез/api/admin/settings. - Проверка Remnawave health и пина версий Panel/Subscription Page.
CI workflow .github/workflows/fullstack-qa.yml запускает этот слой на:
pull_requestвmainиdev;pushвmainиdev;- ручной
workflow_dispatch.
При падении workflow прикладывает Docker Compose logs как artifact.