#!/usr/bin/env pwsh # ╔═══════════════════════════════════════════════════════════════════════════╗ # ║ Единый лаунчер dev / test. APP_ENV из корневого .env решает, что запускать. ║ # ╚═══════════════════════════════════════════════════════════════════════════╝ # development → uvicorn --reload (бэк) + vite (фронт), нативно, в двух окнах # test → docker compose прод-клон (порт 8080) # production → лаунчером НЕ запускается (прод обособлен: docker compose up -d на Pi) # # LOCAL_PUBLIC=vps дополнительно поднимает SSH-туннель на VPS, и dev/test становится # виден снаружи на https://forbidden-stars.ru (нужен настроенный VPS, см. deploy/vps). # # Запуск: .\run.ps1 # Если ругается на политику: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned $ErrorActionPreference = "Stop" $root = $PSScriptRoot $envFile = Join-Path $root ".env" if (-not (Test-Path $envFile)) { Write-Host "Нет .env в корне. Скопируйте: Copy-Item .env.example .env" -ForegroundColor Red exit 1 } # Достаём значение ключа из .env (последнее присвоение побеждает; комментарии игнор). function Get-EnvVal([string]$name, [string]$default) { $val = $default foreach ($line in Get-Content $envFile) { if ($line -match "^\s*$name\s*=\s*([^#\s]+)") { $val = $matches[1].Trim() } } return $val } $appEnv = (Get-EnvVal "APP_ENV" "development").ToLower() $localPublic = (Get-EnvVal "LOCAL_PUBLIC" "local").ToLower() $vpsHost = Get-EnvVal "VPS_TUNNEL_HOST" "" $vpsUser = Get-EnvVal "VPS_TUNNEL_USER" "tunnel" $vpsPort = Get-EnvVal "VPS_TUNNEL_PORT" "9001" Write-Host "APP_ENV = $appEnv LOCAL_PUBLIC = $localPublic" -ForegroundColor Cyan # Поднимает SSH reverse-tunnel: VPS:$vpsPort → localhost:$localPort (в отдельном окне). function Start-VpsTunnel([int]$localPort) { if (-not $vpsHost) { Write-Host "LOCAL_PUBLIC=vps, но VPS_TUNNEL_HOST не задан в .env — туннель пропущен." -ForegroundColor Red return } Write-Host "SSH-туннель: forbidden-stars.ru (VPS:$vpsPort) → localhost:$localPort …" -ForegroundColor Green $ssh = "ssh -N -R ${vpsPort}:localhost:${localPort} " + "-o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes " + "${vpsUser}@${vpsHost}" Start-Process powershell -ArgumentList @( "-NoExit", "-Command", "Write-Host 'SSH-туннель на forbidden-stars.ru. Закрой окно, чтобы остановить.' -ForegroundColor Cyan; $ssh" ) } switch ($appEnv) { "development" { $backend = Join-Path $root "backend" $frontend = Join-Path $root "frontend" $py = Join-Path $backend ".venv\Scripts\python.exe" if (-not (Test-Path $py)) { Write-Host "Нет venv: $py" -ForegroundColor Red Write-Host "Сначала: cd backend; python -m venv .venv; .\.venv\Scripts\Activate.ps1; pip install -e `".[dev]`"" -ForegroundColor Yellow exit 1 } if (-not (Test-Path (Join-Path $frontend "node_modules"))) { Write-Host "Нет node_modules. Сначала: cd frontend; npm install" -ForegroundColor Red exit 1 } Write-Host "Запуск бэка (uvicorn --reload) и фронта (vite) в отдельных окнах…" -ForegroundColor Green Start-Process powershell -ArgumentList @( "-NoExit", "-Command", "Set-Location '$backend'; & '$py' -m uvicorn app.main:app --reload" ) Start-Process powershell -ArgumentList @( "-NoExit", "-Command", "Set-Location '$frontend'; npm run dev" ) Write-Host "" Write-Host " Бэк: http://127.0.0.1:8000 (Swagger: /api/docs)" -ForegroundColor Green Write-Host " Фронт: http://127.0.0.1:5173" -ForegroundColor Green if ($localPublic -eq "vps") { Start-VpsTunnel 5173 Write-Host " Публично: https://forbidden-stars.ru" -ForegroundColor Green } } "test" { $compose = Join-Path $root "docker-compose.test.yml" Write-Host "Сборка и запуск прод-клона в Docker (порт 8080)…" -ForegroundColor Green docker compose -f $compose up --build -d if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } Write-Host "" Write-Host " Открыть: http://localhost:8080 (Swagger: /api/docs)" -ForegroundColor Green Write-Host " Логи: docker compose -f docker-compose.test.yml logs -f" Write-Host " Стоп: docker compose -f docker-compose.test.yml down -v" if ($localPublic -eq "vps") { Start-VpsTunnel 8080 Write-Host " Публично: https://forbidden-stars.ru" -ForegroundColor Green } } "production" { Write-Host "production лаунчером не запускается — прод обособлен." -ForegroundColor Yellow Write-Host "Деплой на Pi (из ветки main): docker compose up -d --build" exit 1 } default { Write-Host "Неизвестный APP_ENV='$appEnv'. Допустимо: development | test | production." -ForegroundColor Red exit 1 } }