Initial commit: ROA2WEB - FastAPI + Vue.js + Telegram Bot
Modern ERP Reports Application with microservices architecture Tech Stack: - Backend: FastAPI + python-oracledb (Oracle DB integration) - Frontend: Vue.js 3 + PrimeVue + Vite - Telegram Bot: python-telegram-bot + SQLite - Infrastructure: Shared database pool, JWT authentication, SSH tunnel Features: - FastAPI backend with async Oracle connection pool - Vue.js 3 responsive frontend with PrimeVue components - Telegram bot alternative interface - Microservices architecture with shared components - Complete deployment support (Linux Docker + Windows IIS) - Comprehensive testing (Playwright E2E + pytest) Repository Structure: - reports-app/ - Main application (backend, frontend, telegram-bot) - shared/ - Shared components (database pool, auth, utils) - deployment/ - Deployment scripts (Linux & Windows) - docs/ - Project documentation - security/ - Security scanning and git hooks
This commit is contained in:
598
deployment/windows/scripts/Install-ROA2WEB.ps1
Normal file
598
deployment/windows/scripts/Install-ROA2WEB.ps1
Normal file
@@ -0,0 +1,598 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
ROA2WEB - Initial Installation Script for Windows Server + IIS
|
||||
|
||||
.DESCRIPTION
|
||||
This script performs complete installation of ROA2WEB on Windows Server:
|
||||
- Checks prerequisites (Admin rights, IIS)
|
||||
- Installs Python 3.11+ if needed
|
||||
- Installs NSSM (service manager)
|
||||
- Installs IIS URL Rewrite and ARR modules
|
||||
- Creates directory structure
|
||||
- Installs Python dependencies
|
||||
- Creates Windows Service for backend
|
||||
- Configures IIS website
|
||||
- Starts all services
|
||||
|
||||
.PARAMETER InstallPath
|
||||
Installation path (default: C:\inetpub\wwwroot\roa2web)
|
||||
|
||||
.PARAMETER PythonVersion
|
||||
Python version to install (default: 3.11.9)
|
||||
|
||||
.PARAMETER ServicePort
|
||||
Backend service port (default: 8000)
|
||||
|
||||
.PARAMETER SkipPython
|
||||
Skip Python installation (use existing Python)
|
||||
|
||||
.PARAMETER SkipIIS
|
||||
Skip IIS configuration
|
||||
|
||||
.EXAMPLE
|
||||
.\Install-ROA2WEB.ps1
|
||||
Standard installation with defaults
|
||||
|
||||
.EXAMPLE
|
||||
.\Install-ROA2WEB.ps1 -InstallPath "D:\Apps\roa2web" -ServicePort 8001
|
||||
Custom installation path and port
|
||||
|
||||
.NOTES
|
||||
Author: ROA2WEB Team
|
||||
Requires: PowerShell 5.1+, Administrator privileges
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$InstallPath = "C:\inetpub\wwwroot\roa2web",
|
||||
[string]$PythonVersion = "3.11.9",
|
||||
[int]$ServicePort = 8000,
|
||||
[string]$IISSiteName = "Default Web Site",
|
||||
[string]$IISAppName = "roa2web",
|
||||
[switch]$CreateNewSite,
|
||||
[switch]$SkipPython,
|
||||
[switch]$SkipIIS
|
||||
)
|
||||
|
||||
# Strict error handling
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
# =============================================================================
|
||||
# CONFIGURATION
|
||||
# =============================================================================
|
||||
|
||||
$script:Config = @{
|
||||
AppName = "ROA2WEB"
|
||||
ServiceName = "ROA2WEB-Backend"
|
||||
ServiceDisplayName = "ROA2WEB Backend Service"
|
||||
ServiceDescription = "FastAPI backend service for ROA2WEB ERP Reports Application"
|
||||
InstallPath = $InstallPath
|
||||
BackendPath = Join-Path $InstallPath "backend"
|
||||
FrontendPath = Join-Path $InstallPath "frontend"
|
||||
LogsPath = Join-Path $InstallPath "logs"
|
||||
TempPath = Join-Path $InstallPath "temp"
|
||||
PythonVersion = $PythonVersion
|
||||
ServicePort = $ServicePort
|
||||
IISSiteName = $IISSiteName
|
||||
IISAppName = $IISAppName
|
||||
IISAppPoolName = "ROA2WEB-AppPool"
|
||||
CreateNewSite = $CreateNewSite
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# HELPER FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
function Write-Step {
|
||||
param([string]$Message)
|
||||
Write-Host "`n[*] $Message" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
function Write-Success {
|
||||
param([string]$Message)
|
||||
Write-Host " [OK] $Message" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Write-Error {
|
||||
param([string]$Message)
|
||||
Write-Host " [ERROR] $Message" -ForegroundColor Red
|
||||
}
|
||||
|
||||
function Write-Warning {
|
||||
param([string]$Message)
|
||||
Write-Host " [WARN] $Message" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
function Test-Administrator {
|
||||
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = [Security.Principal.WindowsPrincipal]$identity
|
||||
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
}
|
||||
|
||||
function Test-CommandExists {
|
||||
param([string]$Command)
|
||||
try {
|
||||
if (Get-Command $Command -ErrorAction Stop) {
|
||||
return $true
|
||||
}
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Install-Chocolatey {
|
||||
Write-Step "Installing Chocolatey package manager..."
|
||||
|
||||
if (Test-CommandExists "choco") {
|
||||
Write-Success "Chocolatey already installed"
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
||||
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
||||
|
||||
# Refresh environment
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
|
||||
Write-Success "Chocolatey installed successfully"
|
||||
} catch {
|
||||
throw "Failed to install Chocolatey: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-Python {
|
||||
Write-Step "Checking Python installation..."
|
||||
|
||||
if ($SkipPython) {
|
||||
Write-Warning "Skipping Python installation (as requested)"
|
||||
return
|
||||
}
|
||||
|
||||
# Check if Python is already installed
|
||||
try {
|
||||
$pythonCmd = Get-Command python -ErrorAction Stop
|
||||
$pythonVersionOutput = & python --version 2>&1
|
||||
if ($pythonVersionOutput -match "Python (\d+\.\d+\.\d+)") {
|
||||
$installedVersion = $matches[1]
|
||||
Write-Success "Python $installedVersion already installed at $($pythonCmd.Source)"
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Python not found, will install..."
|
||||
}
|
||||
|
||||
# Install Python via Chocolatey
|
||||
Write-Step "Installing Python $PythonVersion..."
|
||||
try {
|
||||
choco install python --version=$PythonVersion -y --force
|
||||
|
||||
# Refresh environment
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
|
||||
Write-Success "Python $PythonVersion installed successfully"
|
||||
} catch {
|
||||
throw "Failed to install Python: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-NSSM {
|
||||
Write-Step "Installing NSSM (service manager)..."
|
||||
|
||||
if (Test-Path "C:\nssm\nssm.exe") {
|
||||
Write-Success "NSSM already installed"
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
choco install nssm -y
|
||||
Write-Success "NSSM installed successfully"
|
||||
} catch {
|
||||
throw "Failed to install NSSM: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-IISModules {
|
||||
if ($SkipIIS) {
|
||||
Write-Warning "Skipping IIS configuration (as requested)"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Step "Checking IIS installation..."
|
||||
|
||||
# Detect OS type (Server vs Desktop)
|
||||
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
|
||||
$isServer = $osInfo.ProductType -eq 3 # 1=Workstation, 2=Domain Controller, 3=Server
|
||||
|
||||
# Check if IIS is installed (different cmdlets for Server vs Desktop)
|
||||
$iisInstalled = $false
|
||||
|
||||
if ($isServer) {
|
||||
# Windows Server - use Get-WindowsFeature
|
||||
$iisFeature = Get-WindowsFeature -Name Web-Server -ErrorAction SilentlyContinue
|
||||
$iisInstalled = $iisFeature -and $iisFeature.InstallState -eq "Installed"
|
||||
|
||||
if (-not $iisInstalled) {
|
||||
Write-Error "IIS is not installed. Please install IIS first:"
|
||||
Write-Host " Install-WindowsFeature -Name Web-Server -IncludeManagementTools" -ForegroundColor Yellow
|
||||
throw "IIS not installed"
|
||||
}
|
||||
} else {
|
||||
# Windows Desktop (10/11) - use Get-WindowsOptionalFeature
|
||||
$iisFeature = Get-WindowsOptionalFeature -Online -FeatureName IIS-WebServer -ErrorAction SilentlyContinue
|
||||
$iisInstalled = $iisFeature -and $iisFeature.State -eq "Enabled"
|
||||
|
||||
if (-not $iisInstalled) {
|
||||
Write-Error "IIS is not installed. Please install IIS first:"
|
||||
Write-Host " Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServer -All" -ForegroundColor Yellow
|
||||
Write-Host " Or use: Control Panel -> Programs -> Turn Windows features on/off -> Internet Information Services" -ForegroundColor Yellow
|
||||
throw "IIS not installed"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Success "IIS is installed ($($osInfo.Caption))"
|
||||
|
||||
# Install URL Rewrite Module
|
||||
Write-Step "Installing IIS URL Rewrite Module..."
|
||||
$urlRewriteInstalled = Get-WebConfiguration -Filter "/system.webServer/rewrite" -PSPath "IIS:\" -ErrorAction SilentlyContinue
|
||||
|
||||
if (-not $urlRewriteInstalled) {
|
||||
Write-Warning "URL Rewrite not found, installing..."
|
||||
try {
|
||||
$urlRewriteUrl = "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi"
|
||||
$urlRewritePath = "$env:TEMP\rewrite_amd64.msi"
|
||||
|
||||
Invoke-WebRequest -Uri $urlRewriteUrl -OutFile $urlRewritePath
|
||||
Start-Process msiexec.exe -ArgumentList "/i", $urlRewritePath, "/quiet", "/norestart" -Wait
|
||||
Remove-Item $urlRewritePath -Force
|
||||
|
||||
Write-Success "URL Rewrite Module installed"
|
||||
} catch {
|
||||
Write-Error "Failed to install URL Rewrite: $_"
|
||||
Write-Warning "You can download it manually from: https://www.iis.net/downloads/microsoft/url-rewrite"
|
||||
}
|
||||
} else {
|
||||
Write-Success "URL Rewrite Module already installed"
|
||||
}
|
||||
|
||||
# Install Application Request Routing (ARR)
|
||||
Write-Step "Checking Application Request Routing (ARR)..."
|
||||
try {
|
||||
choco install iis-arr -y
|
||||
Write-Success "ARR installed successfully"
|
||||
} catch {
|
||||
Write-Warning "Could not install ARR via Chocolatey. Download manually from: https://www.iis.net/downloads/microsoft/application-request-routing"
|
||||
}
|
||||
}
|
||||
|
||||
function New-DirectoryStructure {
|
||||
Write-Step "Creating directory structure..."
|
||||
|
||||
$directories = @(
|
||||
$Config.InstallPath,
|
||||
$Config.BackendPath,
|
||||
$Config.FrontendPath,
|
||||
$Config.LogsPath,
|
||||
$Config.TempPath,
|
||||
(Join-Path $Config.BackendPath "logs"),
|
||||
(Join-Path $Config.BackendPath "temp")
|
||||
)
|
||||
|
||||
foreach ($dir in $directories) {
|
||||
if (-not (Test-Path $dir)) {
|
||||
New-Item -ItemType Directory -Path $dir -Force | Out-Null
|
||||
Write-Success "Created: $dir"
|
||||
} else {
|
||||
Write-Success "Already exists: $dir"
|
||||
}
|
||||
}
|
||||
|
||||
# Set permissions (IIS user needs read access)
|
||||
try {
|
||||
$acl = Get-Acl $Config.InstallPath
|
||||
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow")
|
||||
$acl.SetAccessRule($accessRule)
|
||||
Set-Acl -Path $Config.InstallPath -AclObject $acl
|
||||
Write-Success "Permissions set for IIS_IUSRS"
|
||||
} catch {
|
||||
Write-Warning "Could not set permissions: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-PythonDependencies {
|
||||
Write-Step "Installing Python dependencies..."
|
||||
|
||||
$requirementsPath = Join-Path $Config.BackendPath "requirements.txt"
|
||||
|
||||
if (-not (Test-Path $requirementsPath)) {
|
||||
Write-Warning "requirements.txt not found at $requirementsPath"
|
||||
Write-Warning "Please copy backend files first, then run this script again"
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
# Upgrade pip first
|
||||
& python -m pip install --upgrade pip
|
||||
|
||||
# Install dependencies
|
||||
& python -m pip install -r $requirementsPath
|
||||
|
||||
Write-Success "Python dependencies installed successfully"
|
||||
} catch {
|
||||
throw "Failed to install Python dependencies: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function New-WindowsService {
|
||||
Write-Step "Creating Windows Service for backend..."
|
||||
|
||||
# Check if service already exists using nssm (more reliable than Get-Service)
|
||||
# Temporarily disable error action to check service status
|
||||
$oldErrorAction = $ErrorActionPreference
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
$nssmOutput = & nssm status $Config.ServiceName 2>&1
|
||||
$serviceExists = $LASTEXITCODE -eq 0
|
||||
|
||||
$ErrorActionPreference = $oldErrorAction
|
||||
|
||||
if ($serviceExists) {
|
||||
Write-Warning "Service already exists, stopping and removing..."
|
||||
# Try to stop service (may fail if service is broken)
|
||||
& nssm stop $Config.ServiceName 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
# Force remove service
|
||||
& nssm remove $Config.ServiceName confirm 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
Write-Success "Existing service removed"
|
||||
}
|
||||
|
||||
# Get Python path
|
||||
$pythonPath = (Get-Command python).Source
|
||||
$uvicornModule = "uvicorn"
|
||||
$appModule = "app.main:app"
|
||||
|
||||
# NSSM service creation
|
||||
try {
|
||||
# Install service
|
||||
& nssm install $Config.ServiceName $pythonPath "-m" $uvicornModule $appModule "--host" "127.0.0.1" "--port" $Config.ServicePort.ToString() "--workers" "4"
|
||||
|
||||
# Set service configuration
|
||||
& nssm set $Config.ServiceName DisplayName $Config.ServiceDisplayName
|
||||
& nssm set $Config.ServiceName Description $Config.ServiceDescription
|
||||
& nssm set $Config.ServiceName Start SERVICE_AUTO_START
|
||||
& nssm set $Config.ServiceName AppDirectory $Config.BackendPath
|
||||
|
||||
# Set environment variables (PYTHONPATH for shared modules)
|
||||
# Point to the installation root so shared/ modules can be imported
|
||||
$pythonPath = $Config.InstallPath
|
||||
& nssm set $Config.ServiceName AppEnvironmentExtra "PYTHONPATH=$pythonPath"
|
||||
|
||||
# Set logging
|
||||
$stdoutLog = Join-Path $Config.LogsPath "backend-stdout.log"
|
||||
$stderrLog = Join-Path $Config.LogsPath "backend-stderr.log"
|
||||
& nssm set $Config.ServiceName AppStdout $stdoutLog
|
||||
& nssm set $Config.ServiceName AppStderr $stderrLog
|
||||
& nssm set $Config.ServiceName AppStdoutCreationDisposition 4
|
||||
& nssm set $Config.ServiceName AppStderrCreationDisposition 4
|
||||
|
||||
# Set restart policy
|
||||
& nssm set $Config.ServiceName AppExit Default Restart
|
||||
& nssm set $Config.ServiceName AppRestartDelay 5000
|
||||
|
||||
Write-Success "Windows Service created successfully"
|
||||
} catch {
|
||||
throw "Failed to create Windows Service: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Initialize-IISWebsite {
|
||||
if ($SkipIIS) {
|
||||
Write-Warning "Skipping IIS website configuration (as requested)"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Step "Configuring IIS application..."
|
||||
|
||||
Import-Module WebAdministration -ErrorAction Stop
|
||||
|
||||
# Remove existing app pool if present
|
||||
if (Test-Path "IIS:\AppPools\$($Config.IISAppPoolName)") {
|
||||
Write-Warning "Removing existing app pool..."
|
||||
Remove-WebAppPool -Name $Config.IISAppPoolName -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Create Application Pool
|
||||
Write-Step "Creating IIS Application Pool..."
|
||||
New-WebAppPool -Name $Config.IISAppPoolName -Force | Out-Null
|
||||
Set-ItemProperty -Path "IIS:\AppPools\$($Config.IISAppPoolName)" -Name "managedRuntimeVersion" -Value ""
|
||||
Write-Success "Application Pool created: $($Config.IISAppPoolName)"
|
||||
|
||||
if ($CreateNewSite) {
|
||||
# Create new website (old behavior)
|
||||
Write-Step "Creating new IIS Website..."
|
||||
|
||||
# Stop default website if running
|
||||
try {
|
||||
Stop-Website -Name "Default Web Site" -ErrorAction SilentlyContinue
|
||||
Write-Success "Stopped Default Web Site"
|
||||
} catch {
|
||||
Write-Warning "Could not stop Default Web Site: $_"
|
||||
}
|
||||
|
||||
# Remove existing site if present
|
||||
if (Get-Website -Name $Config.IISSiteName -ErrorAction SilentlyContinue) {
|
||||
Write-Warning "Removing existing website..."
|
||||
Remove-Website -Name $Config.IISSiteName -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
New-Website -Name $Config.IISSiteName `
|
||||
-PhysicalPath $Config.FrontendPath `
|
||||
-ApplicationPool $Config.IISAppPoolName `
|
||||
-Port 80 `
|
||||
-Force | Out-Null
|
||||
|
||||
Write-Success "Website created: $($Config.IISSiteName)"
|
||||
|
||||
# Start website
|
||||
Start-Website -Name $Config.IISSiteName
|
||||
Write-Success "Website started: $($Config.IISSiteName)"
|
||||
} else {
|
||||
# Create application under existing site (default behavior)
|
||||
Write-Step "Creating IIS Application under '$($Config.IISSiteName)'..."
|
||||
|
||||
# Verify parent site exists
|
||||
$parentSite = Get-Website -Name $Config.IISSiteName -ErrorAction SilentlyContinue
|
||||
if (-not $parentSite) {
|
||||
throw "Parent website '$($Config.IISSiteName)' does not exist. Use -CreateNewSite to create a new site."
|
||||
}
|
||||
|
||||
# Remove existing application if present
|
||||
$existingApp = Get-WebApplication -Name $Config.IISAppName -Site $Config.IISSiteName -ErrorAction SilentlyContinue
|
||||
if ($existingApp) {
|
||||
Write-Warning "Removing existing application..."
|
||||
Remove-WebApplication -Name $Config.IISAppName -Site $Config.IISSiteName -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Create application
|
||||
New-WebApplication -Name $Config.IISAppName `
|
||||
-Site $Config.IISSiteName `
|
||||
-PhysicalPath $Config.FrontendPath `
|
||||
-ApplicationPool $Config.IISAppPoolName `
|
||||
-Force | Out-Null
|
||||
|
||||
Write-Success "Application created: /$($Config.IISAppName) under $($Config.IISSiteName)"
|
||||
}
|
||||
|
||||
# Copy web.config to frontend path
|
||||
$webConfigSource = Join-Path $PSScriptRoot "..\config\web.config"
|
||||
$webConfigDest = Join-Path $Config.FrontendPath "web.config"
|
||||
|
||||
if (Test-Path $webConfigSource) {
|
||||
Copy-Item -Path $webConfigSource -Destination $webConfigDest -Force
|
||||
Write-Success "web.config copied to frontend path"
|
||||
} else {
|
||||
Write-Warning "web.config not found at $webConfigSource"
|
||||
}
|
||||
}
|
||||
|
||||
function Start-Services {
|
||||
Write-Step "Starting services..."
|
||||
|
||||
# Start backend service
|
||||
try {
|
||||
Start-Service -Name $Config.ServiceName
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
$service = Get-Service -Name $Config.ServiceName
|
||||
if ($service.Status -eq "Running") {
|
||||
Write-Success "Backend service started successfully"
|
||||
} else {
|
||||
Write-Error "Backend service failed to start (Status: $($service.Status))"
|
||||
}
|
||||
} catch {
|
||||
Write-Error "Failed to start backend service: $_"
|
||||
}
|
||||
|
||||
# Test backend health
|
||||
Write-Step "Testing backend health..."
|
||||
Start-Sleep -Seconds 5
|
||||
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri "http://localhost:$($Config.ServicePort)/health" -UseBasicParsing -TimeoutSec 10
|
||||
if ($response.StatusCode -eq 200) {
|
||||
Write-Success "Backend health check passed"
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Backend health check failed (may need time to start): $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Show-Summary {
|
||||
Write-Host "`n" + ("=" * 80) -ForegroundColor Cyan
|
||||
Write-Host " ROA2WEB INSTALLATION COMPLETED" -ForegroundColor Green
|
||||
Write-Host ("=" * 80) -ForegroundColor Cyan
|
||||
|
||||
Write-Host "`nInstallation Details:" -ForegroundColor Yellow
|
||||
Write-Host " Install Path: $($Config.InstallPath)"
|
||||
Write-Host " Backend Path: $($Config.BackendPath)"
|
||||
Write-Host " Frontend Path: $($Config.FrontendPath)"
|
||||
Write-Host " Service Name: $($Config.ServiceName)"
|
||||
Write-Host " Service Port: $($Config.ServicePort)"
|
||||
Write-Host " IIS Site: $($Config.IISSiteName)"
|
||||
|
||||
Write-Host "`nAccess Points:" -ForegroundColor Yellow
|
||||
if ($Config.CreateNewSite) {
|
||||
Write-Host " Web Application: http://localhost"
|
||||
} else {
|
||||
Write-Host " Web Application: http://localhost/$($Config.IISAppName)"
|
||||
}
|
||||
Write-Host " API Backend: http://localhost:$($Config.ServicePort)"
|
||||
Write-Host " API Docs: http://localhost:$($Config.ServicePort)/docs"
|
||||
Write-Host " Health Check: http://localhost:$($Config.ServicePort)/health"
|
||||
|
||||
Write-Host "`nNext Steps:" -ForegroundColor Yellow
|
||||
Write-Host " 1. Copy backend files to: $($Config.BackendPath)"
|
||||
Write-Host " 2. Copy frontend files to: $($Config.FrontendPath)"
|
||||
Write-Host " 3. Configure .env file at: $($Config.BackendPath)\.env"
|
||||
Write-Host " 4. Run: .\Deploy-ROA2WEB.ps1 to deploy updates"
|
||||
|
||||
Write-Host "`nManagement Commands:" -ForegroundColor Yellow
|
||||
Write-Host " Start Service: .\Start-ROA2WEB.ps1"
|
||||
Write-Host " Stop Service: .\Stop-ROA2WEB.ps1"
|
||||
Write-Host " Restart Service: .\Restart-ROA2WEB.ps1"
|
||||
Write-Host " View Logs: Get-Content $($Config.LogsPath)\backend-stdout.log -Tail 50"
|
||||
|
||||
Write-Host "`n" + ("=" * 80) -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# MAIN INSTALLATION FLOW
|
||||
# =============================================================================
|
||||
|
||||
function Main {
|
||||
Write-Host @"
|
||||
|
||||
====================================================================
|
||||
ROA2WEB - Windows Server Installation Script
|
||||
Modern ERP Reports Application with FastAPI + Vue.js + IIS
|
||||
====================================================================
|
||||
|
||||
"@ -ForegroundColor Cyan
|
||||
|
||||
# Check prerequisites
|
||||
Write-Step "Checking prerequisites..."
|
||||
|
||||
if (-not (Test-Administrator)) {
|
||||
Write-Error "This script must be run as Administrator"
|
||||
Write-Host " Right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
Write-Success "Running as Administrator"
|
||||
|
||||
try {
|
||||
# Installation steps
|
||||
Install-Chocolatey
|
||||
Install-Python
|
||||
Install-NSSM
|
||||
Install-IISModules
|
||||
New-DirectoryStructure
|
||||
Install-PythonDependencies
|
||||
New-WindowsService
|
||||
Initialize-IISWebsite
|
||||
Start-Services
|
||||
Show-Summary
|
||||
|
||||
Write-Host "`nInstallation completed successfully!" -ForegroundColor Green
|
||||
|
||||
} catch {
|
||||
Write-Host "`n[FATAL ERROR] Installation failed: $_" -ForegroundColor Red
|
||||
Write-Host $_.ScriptStackTrace -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Run main installation
|
||||
Main
|
||||
Reference in New Issue
Block a user