# TestAjanı onarım: eski uygulama konteynerlerini kaldırır, uygulamayı önbelleksiz yeniden derler ve sürümü doğrular. # Onar-Windows.bat bu betiği çağırır. Veriler (geçmiş, modeller) korunur. $ErrorActionPreference = "Continue" [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $Root = Split-Path -Parent $PSScriptRoot Set-Location $Root $AppUrl = "http://localhost:8000" function Step($m) { Write-Host ""; Write-Host "==> $m" -ForegroundColor Cyan } function Info($m) { Write-Host " $m" } function Health { try { return Invoke-RestMethod -Uri "$AppUrl/api/health" -TimeoutSec 4 } catch { return $null } } Step "1. Bu klasor" $Expected = (Get-Content (Join-Path $Root "VERSION") -ErrorAction SilentlyContinue | Select-Object -First 1) if ($Expected) { $Expected = $Expected.Trim() } Info "Klasor : $Root" Info "Surum : $Expected" Step "2. Su an calisan uygulama" docker info *> $null if ($LASTEXITCODE -ne 0) { Write-Host "HATA: Docker calismiyor. Docker Desktop'i acip tekrar deneyin." -ForegroundColor Red; exit 1 } $h = Health if ($h) { Info ("localhost:8000 surumu: " + $(if ($h.version) { $h.version } else { "(surum bilgisi yok = eski surum)" })) } else { Info "localhost:8000 yanit vermiyor" } $rows = docker ps -a --filter "publish=8000" --format '{{.ID}}|{{.Names}}|{{.Image}}|{{.CreatedAt}}|{{.Labels}}' 2>$null $apps = docker ps -a --filter "label=com.docker.compose.service=app" --format '{{.ID}}|{{.Names}}|{{.Image}}|{{.CreatedAt}}|{{.Labels}}' 2>$null $all = @(@($rows) + @($apps) | Where-Object { $_ } | Sort-Object -Unique) foreach ($r in $all) { $p = $r -split '\|', 5 $proj = if ($p[4] -match 'com\.docker\.compose\.project\.working_dir=([^,]+)') { $Matches[1] } else { "?" } Info "Konteyner $($p[1]) imaj=$($p[2]) olusturma=$($p[3])" Info " klasor=$proj" } Step "3. Eski uygulama konteynerleri kaldiriliyor" foreach ($r in $all) { $p = $r -split '\|', 5 if ($p[2] -match 'ollama') { continue } docker rm -f $p[0] *> $null Info "kaldirildi: $($p[1])" } Step "4. Uygulama onbelleksiz yeniden derleniyor (birkac dakika surebilir)" $composeFiles = @() if (Get-Command nvidia-smi -ErrorAction SilentlyContinue) { $composeFiles = @("-f", "docker-compose.yml", "-f", "docker-compose.gpu.yml") } $hostOllama = $false try { Invoke-WebRequest -Uri "http://localhost:11434/api/tags" -UseBasicParsing -TimeoutSec 3 | Out-Null; $hostOllama = $true } catch { } if ($hostOllama -and -not ((docker ps --format "{{.Names}}") -match "ollama")) { $env:OLLAMA_URL = "http://host.docker.internal:11434"; $profileArgs = @() } else { $env:OLLAMA_URL = "http://ollama:11434"; $profileArgs = @("--profile", "ollama") } docker compose build --no-cache --pull app if ($LASTEXITCODE -ne 0) { Write-Host "HATA: derleme basarisiz (yukaridaki ciktiya bakin)." -ForegroundColor Red; exit 1 } docker compose @composeFiles @profileArgs up -d --force-recreate app if ($LASTEXITCODE -ne 0) { docker compose @profileArgs up -d --force-recreate app } Step "5. Dogrulama" for ($i = 0; $i -lt 60 -and -not (Health); $i++) { Start-Sleep -Seconds 2 } $h = Health $got = if ($h) { $h.version } else { "" } Info "Beklenen: $Expected" Info "Calisan : $got" if ($got -eq $Expected) { Write-Host " [OK] Uygulama guncel." -ForegroundColor Green Start-Process "$AppUrl/?v=$Expected" Write-Host " Tarayici acildi. Eski sayfa hala aciksa o sekmede Ctrl+F5 yapin." -ForegroundColor Green } else { Write-Host "HATA: surum hala uyusmuyor. Bu pencerenin ekran goruntusunu gonderin." -ForegroundColor Red exit 1 }