Created turnkey deployment for Hyper-V VMs and fresh Windows installs. FILES: - deploy-to-vm.ps1: Automated PowerShell deployment script - Checks prerequisites - Builds images (offline packages) - Starts all services - Initializes database - Sets admin password - One command deployment - DEPLOY-TO-VM.md: Complete deployment guide - Multiple copy methods - Manual deployment steps - Troubleshooting - Offline deployment notes USAGE: .\deploy-to-vm.ps1 -SiteName 'west-jefferson' -AdminPassword 'SecurePass!' TIMELINE: 5 minutes from repo copy to running system
137 lines
5.1 KiB
PowerShell
137 lines
5.1 KiB
PowerShell
# ShopDB Docker Deployment Script for Hyper-V VM
|
|
# Run this ON THE VM after copying the repo
|
|
|
|
param(
|
|
[string]$SiteName = "shopdb-vm",
|
|
[string]$AdminPassword = "ChangeMe123!",
|
|
[switch]$Help
|
|
)
|
|
|
|
if ($Help) {
|
|
Write-Host @"
|
|
ShopDB Docker Deployment Script
|
|
|
|
Usage:
|
|
.\deploy-to-vm.ps1 [-SiteName <name>] [-AdminPassword <password>]
|
|
|
|
Parameters:
|
|
-SiteName Site identifier (default: shopdb-vm)
|
|
-AdminPassword Initial admin password (default: ChangeMe123!)
|
|
-Help Show this help
|
|
|
|
Example:
|
|
.\deploy-to-vm.ps1 -SiteName "west-jefferson" -AdminPassword "SecurePass123!"
|
|
|
|
Prerequisites:
|
|
- Docker Desktop installed and running
|
|
- Git Bash or WSL available
|
|
"@
|
|
exit 0
|
|
}
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host "ShopDB Docker Deployment" -ForegroundColor Cyan
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
# Check Docker is running
|
|
Write-Host "[1/8] Checking Docker Desktop..." -ForegroundColor Yellow
|
|
try {
|
|
docker ps | Out-Null
|
|
Write-Host " OK: Docker is running" -ForegroundColor Green
|
|
} catch {
|
|
Write-Host " ERROR: Docker Desktop is not running" -ForegroundColor Red
|
|
Write-Host " Please start Docker Desktop and try again" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# Check if we're in the repo
|
|
Write-Host "[2/8] Checking repository..." -ForegroundColor Yellow
|
|
if (-not (Test-Path "docker-compose.prebuilt.yml")) {
|
|
Write-Host " ERROR: Not in shopdb-flask directory" -ForegroundColor Red
|
|
Write-Host " Please cd to the repository root" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
Write-Host " OK: In repository root" -ForegroundColor Green
|
|
|
|
# Create .env if it doesn't exist
|
|
Write-Host "[3/8] Configuring environment..." -ForegroundColor Yellow
|
|
if (-not (Test-Path ".env")) {
|
|
Copy-Item ".env.docker-dev" ".env"
|
|
Write-Host " Created .env from template" -ForegroundColor Green
|
|
|
|
# Update site name
|
|
(Get-Content ".env") -replace 'SHOPDB_SITE=shopdb-dev', "SHOPDB_SITE=$SiteName" | Set-Content ".env"
|
|
(Get-Content ".env") -replace 'SHOPDB_ENV_LABEL=DOCKER-DEV', "SHOPDB_ENV_LABEL=$SiteName" | Set-Content ".env"
|
|
Write-Host " Configured for site: $SiteName" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " OK: .env already exists" -ForegroundColor Green
|
|
}
|
|
|
|
# Build frontend if needed
|
|
Write-Host "[4/8] Checking frontend build..." -ForegroundColor Yellow
|
|
if (-not (Test-Path "frontend/dist/index.html")) {
|
|
Write-Host " Building frontend (this may take 2-3 minutes)..." -ForegroundColor Yellow
|
|
Set-Location frontend
|
|
npm ci
|
|
npm run build
|
|
Set-Location ..
|
|
Write-Host " OK: Frontend built" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " OK: Frontend already built" -ForegroundColor Green
|
|
}
|
|
|
|
# Build Docker images
|
|
Write-Host "[5/8] Building Docker images..." -ForegroundColor Yellow
|
|
Write-Host " This will take 2-3 minutes (using offline packages)..." -ForegroundColor Yellow
|
|
docker compose -f docker-compose.prebuilt.yml -f docker-compose.backup.yml build
|
|
Write-Host " OK: Images built" -ForegroundColor Green
|
|
|
|
# Start services
|
|
Write-Host "[6/8] Starting services..." -ForegroundColor Yellow
|
|
docker compose -f docker-compose.prebuilt.yml -f docker-compose.backup.yml --profile backup up -d
|
|
Start-Sleep -Seconds 10
|
|
Write-Host " OK: Services started" -ForegroundColor Green
|
|
|
|
# Run migrations
|
|
Write-Host "[7/8] Initializing database..." -ForegroundColor Yellow
|
|
docker exec flask-shopdb-api-1 flask db upgrade
|
|
Write-Host " OK: Database initialized" -ForegroundColor Green
|
|
|
|
# Set admin password
|
|
Write-Host "[8/8] Setting admin password..." -ForegroundColor Yellow
|
|
$passwordHash = docker exec flask-shopdb-api-1 python -c "from werkzeug.security import generate_password_hash; print(generate_password_hash('$AdminPassword'))"
|
|
$dbPassword = (Get-Content ".env" | Select-String "MYSQL_ROOT_PASSWORD=(.+)" | ForEach-Object { $_.Matches.Groups[1].Value })
|
|
|
|
docker exec flask-shopdb-db-1 mysql -uroot -p$dbPassword shopdb_flask -e @"
|
|
UPDATE users SET
|
|
passwordhash = '$passwordHash',
|
|
failedlogins = 0,
|
|
lockeduntil = NULL
|
|
WHERE username = 'admin';
|
|
"@
|
|
Write-Host " OK: Admin password set" -ForegroundColor Green
|
|
|
|
Write-Host ""
|
|
Write-Host "========================================" -ForegroundColor Green
|
|
Write-Host "Deployment Complete!" -ForegroundColor Green
|
|
Write-Host "========================================" -ForegroundColor Green
|
|
Write-Host ""
|
|
Write-Host "Access ShopDB at: https://localhost:5001" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host "Login credentials:" -ForegroundColor Yellow
|
|
Write-Host " Username: admin" -ForegroundColor White
|
|
Write-Host " Password: $AdminPassword" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "Services running:" -ForegroundColor Yellow
|
|
docker ps --format "table {{.Names}}\t{{.Status}}"
|
|
Write-Host ""
|
|
Write-Host "To view logs:" -ForegroundColor Yellow
|
|
Write-Host " docker logs -f flask-shopdb-api-1" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "To stop:" -ForegroundColor Yellow
|
|
Write-Host " docker compose -f docker-compose.prebuilt.yml -f docker-compose.backup.yml down" -ForegroundColor White
|
|
Write-Host ""
|