Spaces:
Running
Running
| # scripts/dev-up.ps1 | |
| # --------------------------------------------------------------------------- | |
| # Smoke up + health verification for the local docker compose stack. | |
| # | |
| # Usage (from repo root): | |
| # pwsh -File scripts/dev-up.ps1 | |
| # pwsh -File scripts/dev-up.ps1 -Rebuild # force --build | |
| # pwsh -File scripts/dev-up.ps1 -InfraOnly # only postgres/redis/minio | |
| # | |
| # What it does: | |
| # 1. Pre-flight: docker daemon, port collisions (5432/6379/9000/9001/8000), | |
| # ML model snapshot directory. | |
| # 2. docker compose up -d (infra first, then backend + worker). | |
| # 3. Poll health endpoints: | |
| # - postgres pg_isready | |
| # - redis PING | |
| # - minio /minio/health/live | |
| # - backend http://localhost:8000/health | |
| # 4. Print summary URLs. | |
| # --------------------------------------------------------------------------- | |
| [CmdletBinding()] | |
| param( | |
| [switch]$Rebuild, | |
| [switch]$InfraOnly | |
| ) | |
| $ErrorActionPreference = "Stop" | |
| $RepoRoot = (Resolve-Path "$PSScriptRoot\..").Path | |
| Push-Location $RepoRoot | |
| function Section($msg) { Write-Host "`n=== $msg ===" -ForegroundColor Cyan } | |
| function OK($msg) { Write-Host " ok: $msg" -ForegroundColor Green } | |
| function Warn($msg) { Write-Host " warn: $msg" -ForegroundColor Yellow } | |
| function Fail($msg) { Write-Host " FAIL: $msg" -ForegroundColor Red } | |
| function Test-Port($port) { | |
| $listener = $null | |
| try { | |
| $listener = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Loopback, $port) | |
| $listener.Start() | |
| return $true # free | |
| } catch { | |
| return $false # in use | |
| } finally { | |
| if ($listener) { $listener.Stop() } | |
| } | |
| } | |
| # ---------- 1. Pre-flight ---------- | |
| Section "Pre-flight checks" | |
| try { docker info --format "{{.ServerVersion}}" | Out-Null; OK "docker daemon reachable" } | |
| catch { Fail "docker daemon not reachable. Start Docker Desktop."; Pop-Location; exit 1 } | |
| $ports = @(5432, 6379, 9000, 9001, 8000) | |
| $collisions = @() | |
| foreach ($p in $ports) { | |
| if (-not (Test-Port $p)) { | |
| $collisions += $p | |
| Warn "port $p is already in use on the host" | |
| } else { | |
| OK "port $p free" | |
| } | |
| } | |
| if ($collisions.Count -gt 0) { | |
| Warn "Port collisions: $($collisions -join ', '). 'docker compose up' will fail to bind these." | |
| Warn "Stop the conflicting process or edit docker-compose.yml port mappings." | |
| } | |
| # Model snapshot dir check (override via MODEL_SNAPSHOT_DIR) | |
| $defaultSnapshot = Join-Path $RepoRoot "services\ml\runs\bundles\full_20260515_044630\_SNAPSHOT_FOR_BUILD" | |
| $snapshot = if ($env:MODEL_SNAPSHOT_DIR) { $env:MODEL_SNAPSHOT_DIR } else { $defaultSnapshot } | |
| if (-not (Test-Path $snapshot)) { | |
| Warn "ML snapshot dir missing: $snapshot" | |
| # Try fallback: most recent bundle under services/ml/runs/bundles/ | |
| $bundleRoot = Join-Path $RepoRoot "services\ml\runs\bundles" | |
| if (Test-Path $bundleRoot) { | |
| $candidate = Get-ChildItem $bundleRoot -Directory -Filter "full_*" | | |
| Sort-Object LastWriteTime -Descending | | |
| Select-Object -First 1 | |
| if ($candidate) { | |
| $fallback = Join-Path $candidate.FullName "_SNAPSHOT_FOR_BUILD" | |
| if (Test-Path $fallback) { | |
| $env:MODEL_SNAPSHOT_DIR = $fallback | |
| OK "fallback snapshot dir set: $fallback" | |
| } else { | |
| Warn "No _SNAPSHOT_FOR_BUILD under $($candidate.FullName). Backend will start without ML weights." | |
| } | |
| } | |
| } | |
| } else { | |
| OK "model snapshot dir: $snapshot" | |
| } | |
| # ---------- 2. Compose up ---------- | |
| Section "docker compose up (infrastructure)" | |
| $buildFlag = if ($Rebuild) { "--build" } else { "" } | |
| # Infra first so dependencies resolve cleanly. | |
| $infraServices = @("postgres", "redis", "minio", "minio-init") | |
| & docker compose up -d @infraServices | |
| if ($LASTEXITCODE -ne 0) { Fail "docker compose up (infra) failed"; Pop-Location; exit 1 } | |
| OK "infra services started" | |
| if (-not $InfraOnly) { | |
| Section "docker compose up (backend + worker)" | |
| $appServices = @("backend", "worker") | |
| if ($Rebuild) { | |
| & docker compose up -d --build @appServices | |
| } else { | |
| & docker compose up -d @appServices | |
| } | |
| if ($LASTEXITCODE -ne 0) { Fail "docker compose up (app) failed"; Pop-Location; exit 1 } | |
| OK "backend + worker started" | |
| } | |
| # ---------- 3. Health checks ---------- | |
| Section "Health checks" | |
| function Wait-For($name, [ScriptBlock]$probe, [int]$timeoutSec = 90) { | |
| $deadline = (Get-Date).AddSeconds($timeoutSec) | |
| while ((Get-Date) -lt $deadline) { | |
| try { | |
| if (& $probe) { OK "$name healthy"; return $true } | |
| } catch { } | |
| Start-Sleep -Seconds 2 | |
| } | |
| Fail "$name did not become healthy within ${timeoutSec}s" | |
| return $false | |
| } | |
| $allHealthy = $true | |
| $allHealthy = (Wait-For "postgres" { | |
| docker exec hasarui-postgres pg_isready -U postgres -d arac_hasar 2>&1 | Out-Null | |
| $LASTEXITCODE -eq 0 | |
| } 60) -and $allHealthy | |
| $allHealthy = (Wait-For "redis" { | |
| (docker exec hasarui-redis redis-cli ping 2>&1).Trim() -eq "PONG" | |
| } 30) -and $allHealthy | |
| $allHealthy = (Wait-For "minio" { | |
| try { | |
| $r = Invoke-WebRequest "http://localhost:9000/minio/health/live" -UseBasicParsing -TimeoutSec 3 | |
| $r.StatusCode -eq 200 | |
| } catch { $false } | |
| } 45) -and $allHealthy | |
| if (-not $InfraOnly) { | |
| $allHealthy = (Wait-For "backend /health" { | |
| try { | |
| $r = Invoke-WebRequest "http://localhost:8000/health" -UseBasicParsing -TimeoutSec 3 | |
| $r.StatusCode -eq 200 | |
| } catch { $false } | |
| } 180) -and $allHealthy | |
| } | |
| # ---------- 4. Summary ---------- | |
| Section "Summary" | |
| docker compose ps | |
| Write-Host "" | |
| Write-Host "URLs:" -ForegroundColor Cyan | |
| Write-Host " API health -> http://localhost:8000/health" | |
| Write-Host " API docs -> http://localhost:8000/docs" | |
| Write-Host " MinIO console -> http://localhost:9001 (minioadmin / minioadmin)" | |
| Write-Host " Postgres -> postgresql://postgres:postgres@localhost:5432/arac_hasar" | |
| Write-Host "" | |
| Write-Host "Next: pnpm --filter @arac-hasar/web dev # http://localhost:3000" | |
| Pop-Location | |
| if (-not $allHealthy) { exit 1 } | |