# MYP Backend - Windows PowerShell Server Start # Startet den Backend-Server vollstaendig unabhaengig vom Frontend param( [switch]$Production, [switch]$Development, [switch]$Logs, [switch]$Help ) # Farben fuer PowerShell $Red = "Red" $Green = "Green" $Yellow = "Yellow" $Blue = "Cyan" function Write-Log { param([string]$Message, [string]$Color = "White") $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Write-Host "[$timestamp] $Message" -ForegroundColor $Color } function Write-Success { param([string]$Message) Write-Log "SUCCESS: $Message" -Color $Green } function Write-Warning { param([string]$Message) Write-Log "WARNING: $Message" -Color $Yellow } function Write-Error { param([string]$Message) Write-Log "FEHLER: $Message" -Color $Red } # Banner Write-Host "========================================" -ForegroundColor $Blue Write-Host "MYP Backend - Standalone Server Start" -ForegroundColor $Blue Write-Host "========================================" -ForegroundColor $Blue if ($Help) { Write-Host "Verwendung: .\start-backend-server.ps1 [OPTIONEN]" Write-Host "" Write-Host "OPTIONEN:" Write-Host " -Production Produktionsmodus (Gunicorn)" Write-Host " -Development Entwicklungsmodus (Flask Dev Server)" Write-Host " -Logs Zeige Live-Logs" Write-Host " -Help Zeige diese Hilfe" Write-Host "" Write-Host "BEISPIELE:" Write-Host " .\start-backend-server.ps1 -Development" Write-Host " .\start-backend-server.ps1 -Production" Write-Host " .\start-backend-server.ps1 -Development -Logs" exit 0 } # Bestimme Ausfuehrungsmodus $RunMode = "development" if ($Production) { $RunMode = "production" Write-Log "Produktionsmodus aktiviert" -Color $Blue } elseif ($Development) { $RunMode = "development" Write-Log "Entwicklungsmodus aktiviert" -Color $Blue } else { $RunMode = "development" Write-Log "Standard-Entwicklungsmodus aktiviert" -Color $Blue } # Arbeitsverzeichnis pruefen $CurrentDir = Get-Location Write-Log "Arbeitsverzeichnis: $CurrentDir" if (-not (Test-Path "app.py")) { Write-Error "app.py nicht gefunden! Bitte im Backend-Verzeichnis ausfuehren." exit 1 } # Python-Installation pruefen Write-Log "Pruefe Python-Installation..." -Color $Blue try { $PythonVersion = python --version 2>&1 Write-Log "Python-Version: $PythonVersion" Write-Success "Python-Installation verifiziert" } catch { Write-Error "Python ist nicht installiert oder nicht im PATH!" exit 1 } # Verbesserte Funktion zum Parsen der Umgebungsvariablen function Set-EnvironmentFromFile { param([string]$FilePath) if (-not (Test-Path $FilePath)) { Write-Warning "$FilePath nicht gefunden" return } Write-Log "Lade Backend-Umgebungsvariablen aus $FilePath..." -Color $Blue try { $EnvContent = Get-Content $FilePath -Raw $Lines = $EnvContent -split "`r?`n" foreach ($Line in $Lines) { # Ueberspringe leere Zeilen und Kommentare if ([string]::IsNullOrWhiteSpace($Line) -or $Line.TrimStart().StartsWith('#')) { continue } # Finde den ersten = Zeichen $EqualIndex = $Line.IndexOf('=') if ($EqualIndex -le 0) { continue } # Extrahiere Key und Value $Key = $Line.Substring(0, $EqualIndex).Trim() $Value = $Line.Substring($EqualIndex + 1).Trim() # Entferne umgebende Anfuehrungszeichen, falls vorhanden if (($Value.StartsWith('"') -and $Value.EndsWith('"')) -or ($Value.StartsWith("'") -and $Value.EndsWith("'"))) { $Value = $Value.Substring(1, $Value.Length - 2) } # Setze Umgebungsvariable if (-not [string]::IsNullOrWhiteSpace($Key)) { [Environment]::SetEnvironmentVariable($Key, $Value, "Process") Write-Log "Geladen: $Key" -Color $Blue } } # Ueberschreibe FLASK_ENV mit dem gewaehlten Modus [Environment]::SetEnvironmentVariable("FLASK_ENV", $RunMode, "Process") Write-Success "Umgebungsvariablen erfolgreich geladen" } catch { Write-Error "Fehler beim Laden der Umgebungsvariablen: $_" Write-Warning "Verwende Standard-Umgebungsvariablen" } } # Umgebungsvariablen laden Set-EnvironmentFromFile "env.backend" # Notwendige Verzeichnisse erstellen Write-Log "Pruefe Verzeichnisse..." -Color $Blue $Directories = @("instance", "logs", "uploads") foreach ($Dir in $Directories) { if (-not (Test-Path $Dir)) { New-Item -ItemType Directory -Path $Dir | Out-Null Write-Log "Verzeichnis erstellt: $Dir" } } # Dependencies pruefen Write-Log "Pruefe Python-Dependencies..." -Color $Blue if (Test-Path "requirements.txt") { try { pip install -r requirements.txt --quiet Write-Success "Dependencies aktualisiert" } catch { Write-Warning "Fehler beim Aktualisieren der Dependencies: $_" } } else { Write-Warning "requirements.txt nicht gefunden" } # Datenbank initialisieren Write-Log "Initialisiere Datenbank..." -Color $Blue try { $env:FLASK_APP = "app.py" # Erstelle temporaere Python-Datei fuer Datenbank-Initialisierung $TempInitFile = "temp_init.py" $InitCode = "from app import create_app, init_db`n" $InitCode += "app = create_app('$RunMode')`n" $InitCode += "with app.app_context():`n" $InitCode += " init_db()`n" $InitCode += " print('Datenbank initialisiert')" $InitCode | Out-File -FilePath $TempInitFile -Encoding UTF8 python $TempInitFile Remove-Item $TempInitFile -Force Write-Success "Datenbank initialisiert" } catch { Write-Error "Fehler bei der Datenbank-Initialisierung: $_" if (Test-Path $TempInitFile) { Remove-Item $TempInitFile -Force } exit 1 } # Port pruefen $Port = 5000 if ($env:PORT) { $Port = [int]$env:PORT } $PortInUse = Get-NetTCPConnection -LocalPort $Port -ErrorAction SilentlyContinue if ($PortInUse) { Write-Warning "Port $Port ist bereits belegt!" $Port = 5001 Write-Log "Verwende alternativen Port $Port..." } # Server starten basierend auf Modus if ($RunMode -eq "production") { Write-Log "Starte Backend-Server im Produktionsmodus..." -Color $Blue # Pruefe Gunicorn try { gunicorn --version | Out-Null Write-Log "Verwende Gunicorn fuer Produktionsbetrieb" } catch { Write-Error "Gunicorn ist nicht installiert! Installiere mit: pip install gunicorn" exit 1 } # Gunicorn Konfiguration $Workers = if ($env:WORKERS) { $env:WORKERS } else { 4 } $BindAddress = if ($env:BIND_ADDRESS) { $env:BIND_ADDRESS } else { "0.0.0.0:$Port" } $Timeout = if ($env:TIMEOUT) { $env:TIMEOUT } else { 30 } Write-Log "Backend-Server startet auf $BindAddress mit $Workers Workern..." # Starte Gunicorn $GunicornCmd = "gunicorn --bind $BindAddress --workers $Workers --timeout $Timeout wsgi:application" if ($Logs) { Write-Log "Starte mit Live-Logs..." -Color $Blue Invoke-Expression $GunicornCmd } else { Write-Log "Starte im Hintergrund..." -Color $Blue Start-Process -FilePath "gunicorn" -ArgumentList "--bind", $BindAddress, "--workers", $Workers, "--timeout", $Timeout, "wsgi:application" -NoNewWindow # Warte auf Server-Start Write-Log "Warte auf Backend-Service..." -Color $Blue $Counter = 0 $TimeoutSeconds = 60 do { Start-Sleep -Seconds 1 $Counter++ try { $Response = Invoke-WebRequest -Uri "http://localhost:$Port/monitoring/health/simple" -Method GET -TimeoutSec 5 -UseBasicParsing if ($Response.StatusCode -eq 200) { Write-Success "Backend-Server ist bereit!" break } } catch { # Ignoriere Fehler waehrend der Startphase } if ($Counter % 10 -eq 0) { $StatusMessage = "Warte auf Backend-Service... ($Counter/$TimeoutSeconds Sekunden)" Write-Log $StatusMessage } } while ($Counter -lt $TimeoutSeconds) if ($Counter -eq $TimeoutSeconds) { Write-Error "Backend-Service konnte nicht gestartet werden!" exit 1 } } } else { Write-Log "Starte Backend-Server im Entwicklungsmodus..." -Color $Blue # Flask-Entwicklungsserver $env:FLASK_APP = "app.py" $env:FLASK_ENV = "development" $env:FLASK_DEBUG = "1" Write-Log "Backend-Server startet auf Port $Port..." if ($Logs) { Write-Log "Starte mit Live-Logs..." -Color $Blue python -m flask run --host=0.0.0.0 --port=$Port } else { Write-Log "Starte im Hintergrund..." -Color $Blue $FlaskProcess = Start-Process -FilePath "python" -ArgumentList "-m", "flask", "run", "--host=0.0.0.0", "--port=$Port" -NoNewWindow -PassThru # Warte auf Server-Start Write-Log "Warte auf Backend-Service..." -Color $Blue $Counter = 0 $TimeoutSeconds = 60 do { Start-Sleep -Seconds 1 $Counter++ try { $Response = Invoke-WebRequest -Uri "http://localhost:$Port/monitoring/health/simple" -Method GET -TimeoutSec 5 -UseBasicParsing if ($Response.StatusCode -eq 200) { Write-Success "Backend-Server ist bereit!" break } } catch { # Ignoriere Fehler waehrend der Startphase } if ($Counter % 10 -eq 0) { $StatusMessage = "Warte auf Backend-Service... ($Counter/$TimeoutSeconds Sekunden)" Write-Log $StatusMessage } } while ($Counter -lt $TimeoutSeconds) if ($Counter -eq $TimeoutSeconds) { Write-Error "Backend-Service konnte nicht gestartet werden!" if ($FlaskProcess -and !$FlaskProcess.HasExited) { $FlaskProcess.Kill() } exit 1 } } } # URLs anzeigen Write-Host "" Write-Success "Backend-Server erfolgreich gestartet!" Write-Host "" Write-Host "Backend-API: http://localhost:$Port" -ForegroundColor $Green Write-Host "Backend-Health: http://localhost:$Port/monitoring/health/simple" -ForegroundColor $Green Write-Host "Backend-Test: http://localhost:$Port/api/test" -ForegroundColor $Green Write-Host "" if ($RunMode -eq "development") { Write-Host "Entwicklungsmodus aktiv:" -ForegroundColor $Blue Write-Host "- Debug-Modus ist aktiviert" -ForegroundColor $White Write-Host "- Automatisches Neuladen bei Aenderungen" -ForegroundColor $White Write-Host "- Detaillierte Fehlermeldungen" -ForegroundColor $White } else { Write-Host "Produktionsmodus aktiv:" -ForegroundColor $Blue Write-Host "- Gunicorn mit $Workers Workern" -ForegroundColor $White Write-Host "- Optimiert fuer Performance" -ForegroundColor $White Write-Host "- Logging aktiviert" -ForegroundColor $White } Write-Host "" # Logs anzeigen (optional) if ($Logs -and $RunMode -eq "development") { Write-Log "Zeige Backend-Logs (Strg+C zum Beenden):" -Color $Blue if (Test-Path "logs\myp.log") { Get-Content "logs\myp.log" -Wait } else { Write-Warning "Keine Log-Datei gefunden" } } if (!$Logs) { Write-Log "Verwende Strg+C um den Server zu stoppen" -Color $Blue # Warte auf Benutzereingabe try { while ($true) { Start-Sleep -Seconds 1 } } catch { Write-Log "Server wird beendet..." -Color $Yellow } }