Files
netrunner-backend/DEPLOYMENT.md
T
nineap 1a26403afb Переключить dev Caddy на порт 443 вместо 8443
Telegram Login Widget в браузере требует именно порт 443 — его CSP
frame-ancestors от oauth.telegram.org не учитывает порт домена и всегда
подразумевает дефолтный порт схемы, поэтому на 8443 виджет рендерился, но
iframe блокировался как cross-origin. VPN-нода, ранее занимавшая 443 на
dev VPS, перенесена на другой порт, так что конфликта больше нет.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-05 20:00:09 +07:00

6.8 KiB
Raw Blame History

Netrunner Control Plane — разработка и деплой

Локальная разработка (fully-dockerized, hot-reload)

Весь стек поднимается одной командой — Postgres, Redis и приложение с автоперекомпиляцией (cargo-watch). Локальный хостовый Rust не нужен.

make dev          # db + redis + app (http://localhost:8080)
make dev-logs     # логи приложения
make dev-down     # остановить (тома/кеши сохраняются)
make clean        # снести стек вместе с БД и кешем компиляции
  • Конфиг — .env.dev (бот выключен: BOT_ENABLED=false, реальный токен Telegram не нужен).
  • Миграции накатываются автоматически при старте app (cargo run -- --migrate).
  • Healthcheck: GET /health (liveness), GET /health/ready (readiness, пингует БД).
  • Первый запуск компилирует всё (несколько минут); дальше — инкрементально через тома target_cache / cargo_registry.

Качество кода (то же, что гоняет CI):

make fmt          # форматирование
make lint         # clippy -D warnings
make test         # тесты (нужен Postgres + DATABASE_URL)

Пайплайн (CI/CD)

Три воркфлоу в .github/workflows/:

Workflow Триггер Что делает
ci.yml PR, push в main fmt --check, clippy -D warnings, тесты на эфемерном Postgres
build.yml push в main, тег v*, вручную Собирает Docker-образ (cargo-chef + GHA-кеш слоёв) и пушит в GHCR
deploy.ymldeploy-dev авто, сразу после успешного build.yml на main SSH на dev VPS: pull образа latest → миграции → перезапуск (docker-compose.dev-remote.yml)
deploy.ymldeploy-prod только вручную (Actions → Run workflow) SSH на прод VPS: pull образа → миграции → перезапуск (docker-compose.prod.yml)

Компиляция Rust происходит в GitHub Actions, а не на машине разработчика и не на VPS. Сервер только тянет готовый образ — деплой занимает секунды. Сборка не требует доступа к БД (sqlx работает в offline-режиме).

Ручной деплой (прод)

GitHub → ActionsDeployRun workflow (можно указать тег образа, по умолчанию latest).

Dev-окружение отдельного ручного шага не требует — обновляется само после каждого успешного билда main.

Секреты GitHub (Settings → Secrets → Actions)

  • VPS_IP / SSH_PRIVATE_KEY — прод-сервер
  • DEV_VPS_IP / DEV_SSH_PRIVATE_KEY — dev-сервер (45.76.161.137, DNS dev.netrunner-vpn.com; на нём же по аналогии деплоится dev-версия netrunner-landing, см. её DEPLOYMENT/README). Домен, а не голый IP, используется во всех browser-facing URL (WEB_APP_BASE_URL, CORS_ALLOWED_ORIGINS и т.п.) — Telegram Login Widget не работает на IP (/setdomain в BotFather принимает только доменное имя).
  • GHCR_TOKEN — токен GHCR с правом read:packages (для pull на VPS, обоих)

GITHUB_TOKEN для push в GHCR выдаётся автоматически.

Отдельно на самом dev VPS (не GitHub-секрет, а переменная в .env рядом с docker-compose.dev-remote.yml) — CF_API_TOKEN: Cloudflare-токен для Caddy (DNS-01 challenge, см. ниже), шаблон "Edit zone DNS", ограниченный зоной netrunner-vpn.com. Не Global API Key.

Что должно лежать на VPS (/root/netrunner-core)

  • docker-compose.prod.yml
  • .env (прод-секреты; APP_ENV=production, BOT_ENABLED=true, реальные токены)
  • keys/netrunner_master_ed25519[.pub] — мастер-ключ для провижининга нод
  • конфиги мониторинга: prometheus.yml, loki-config.yml, promtail-config.yml, grafana-datasources.yml

Прод-стек (docker-compose.prod.yml) поднимает: migrate (one-shot миграции) → app (с healthcheck) + db + redis + Prometheus/Loki/Promtail/Grafana.

Что должно лежать на dev VPS (/root/netrunner-core)

  • docker-compose.dev-remote.yml, Dockerfile.caddy, Caddyfile.dev (все три синкает CI при каждом deploy-dev, руками копировать не нужно)
  • .env (см. .env.dev-remote.example — свои JWT_SECRET/ARGON_SALT/DB_PASSWORD, CF_API_TOKEN, CORS_ALLOWED_ORIGINS/CSRF_ALLOWED_ORIGINS включают origin dev-лендинга и Caddy-порта на этом же хосте)
  • keys/netrunner_master_ed25519[.pub] — свой мастер-ключ, отдельный от прода

Dev-стек: migrateapp (порт 8080, обычный HTTP, без TLS) + db + redis

  • caddy (порт 443, реальный TLS через DNS-01/Cloudflare — см. Caddyfile.dev). Caddy здесь нужен по двум причинам: Telegram Web Apps (кнопки бота "Личный Кабинет"/"Тарифы"/"Синдикат") требуют https:// URL, а Telegram Login Widget в обычном браузере требует именно порт 443 (его CSP frame-ancestors не учитывает порт и всегда подразумевает дефолтный порт схемы). Порт 80 на этом VPS закрыт — обычный HTTP-01 challenge не проходит, поэтому DNS-01. Все браузерные auth-флоу (бот, лендинг) должны идти через Caddy на 443, не напрямую в :8080COOKIE_SECURE=true (как в проде), и Secure-cookie по голому HTTP на :8080 браузер по-прежнему отбросит.

Локальная сборка образа (фолбэк, обычно не нужно)

make build-image   # docker build -t $IMAGE .
make push-image    # docker push $IMAGE
# или ./deploy.sh — собрать и запушить разом