Files
inventory-barcode-system/scripts/deploy.ps1

292 lines
8.1 KiB
PowerShell

# Inventory Barcode System Deployment Script (PowerShell)
# This script handles production deployment with Docker on Windows
param(
[Parameter(Position=0)]
[ValidateSet("deploy", "rollback", "status", "logs", "stop", "restart")]
[string]$Action = "deploy"
)
# Configuration
$APP_NAME = "inventory-barcode-system"
$DOCKER_IMAGE = "$APP_NAME:latest"
$CONTAINER_NAME = "$APP_NAME-container"
$BACKUP_DIR = "./data/backups"
$LOG_FILE = "./logs/deployment.log"
# Ensure log directory exists
if (!(Test-Path -Path "./logs")) {
New-Item -ItemType Directory -Path "./logs" -Force | Out-Null
}
# Logging functions
function Write-Log {
param([string]$Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Write-Host "[$timestamp] $Message" -ForegroundColor Green
"[$timestamp] $Message" | Out-File -FilePath $LOG_FILE -Append
}
function Write-Error-Log {
param([string]$Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Write-Host "[ERROR] $Message" -ForegroundColor Red
"[ERROR] $Message" | Out-File -FilePath $LOG_FILE -Append
exit 1
}
function Write-Warning-Log {
param([string]$Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Write-Host "[WARNING] $Message" -ForegroundColor Yellow
"[WARNING] $Message" | Out-File -FilePath $LOG_FILE -Append
}
# Check prerequisites
function Test-Prerequisites {
Write-Log "Checking prerequisites..."
# Check if Docker is installed
try {
docker --version | Out-Null
}
catch {
Write-Error-Log "Docker is not installed. Please install Docker Desktop first."
}
# Check if Docker Compose is available
try {
docker-compose --version | Out-Null
}
catch {
Write-Error-Log "Docker Compose is not available. Please ensure Docker Desktop is properly installed."
}
# Check if .env file exists
if (!(Test-Path -Path ".env")) {
Write-Warning-Log ".env file not found. Creating from .env.example..."
if (Test-Path -Path ".env.example") {
Copy-Item ".env.example" ".env"
Write-Log "Please edit .env file with your configuration before continuing."
exit 0
}
else {
Write-Error-Log ".env.example file not found. Cannot create .env file."
}
}
Write-Log "Prerequisites check completed successfully."
}
# Create necessary directories
function New-Directories {
Write-Log "Creating necessary directories..."
$directories = @("data/exports", "data/backups", "data/temp", "logs")
foreach ($dir in $directories) {
if (!(Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force | Out-Null
}
}
Write-Log "Directories created successfully."
}
# Backup existing database
function Backup-Database {
if (Test-Path -Path "./inventory.db") {
Write-Log "Backing up existing database..."
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$backupFile = "$BACKUP_DIR/pre-deployment-backup-$timestamp.db"
if (!(Test-Path -Path $BACKUP_DIR)) {
New-Item -ItemType Directory -Path $BACKUP_DIR -Force | Out-Null
}
Copy-Item "./inventory.db" $backupFile
Write-Log "Database backed up to: $backupFile"
}
else {
Write-Log "No existing database found. Skipping backup."
}
}
# Build Docker image
function Build-Image {
Write-Log "Building Docker image..."
$result = docker build -t $DOCKER_IMAGE .
if ($LASTEXITCODE -eq 0) {
Write-Log "Docker image built successfully."
}
else {
Write-Error-Log "Failed to build Docker image."
}
}
# Stop existing container
function Stop-Existing {
Write-Log "Stopping existing container..."
$existingContainer = docker ps -q -f name=$CONTAINER_NAME
if ($existingContainer) {
docker stop $CONTAINER_NAME | Out-Null
docker rm $CONTAINER_NAME | Out-Null
Write-Log "Existing container stopped and removed."
}
else {
Write-Log "No existing container found."
}
}
# Deploy with Docker Compose
function Start-Deployment {
Write-Log "Deploying application with Docker Compose..."
# Stop existing services
docker-compose down | Out-Null
# Start services
docker-compose up -d
if ($LASTEXITCODE -eq 0) {
Write-Log "Application deployed successfully."
}
else {
Write-Error-Log "Failed to deploy application."
}
}
# Health check
function Test-Health {
Write-Log "Performing health check..."
# Wait for application to start
Start-Sleep -Seconds 10
# Check if container is running
$runningContainer = docker ps -q -f name=$APP_NAME
if (!$runningContainer) {
Write-Error-Log "Container is not running."
}
# Check application health endpoint
$maxAttempts = 30
$attempt = 1
while ($attempt -le $maxAttempts) {
try {
$response = Invoke-WebRequest -Uri "http://localhost:3000/health" -UseBasicParsing -TimeoutSec 5
if ($response.StatusCode -eq 200) {
Write-Log "Health check passed. Application is running."
return
}
}
catch {
# Continue to retry
}
Write-Log "Health check attempt $attempt/$maxAttempts failed. Retrying in 5 seconds..."
Start-Sleep -Seconds 5
$attempt++
}
Write-Error-Log "Health check failed after $maxAttempts attempts."
}
# Show deployment status
function Show-Status {
Write-Log "Deployment Status:"
Write-Host ""
Write-Host "Container Status:"
docker ps -f name=$APP_NAME
Write-Host ""
Write-Host "Application Logs (last 20 lines):"
docker-compose logs --tail=20
Write-Host ""
Write-Host "Access the application at: http://localhost:3000"
Write-Host "Health check endpoint: http://localhost:3000/health"
}
# Rollback function
function Start-Rollback {
Write-Warning-Log "Rolling back deployment..."
# Stop current deployment
docker-compose down | Out-Null
# Restore database backup if exists
$latestBackup = Get-ChildItem -Path "$BACKUP_DIR/pre-deployment-backup-*.db" -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1
if ($latestBackup) {
Write-Log "Restoring database from: $($latestBackup.FullName)"
Copy-Item $latestBackup.FullName "./inventory.db"
}
Write-Warning-Log "Rollback completed. Please check your previous deployment."
}
# Main deployment function
function Start-MainDeployment {
Write-Log "Starting deployment of $APP_NAME..."
try {
Test-Prerequisites
New-Directories
Backup-Database
Build-Image
Stop-Existing
Start-Deployment
Test-Health
Show-Status
Write-Log "Deployment completed successfully!"
}
catch {
Write-Error-Log "Deployment failed: $($_.Exception.Message)"
Start-Rollback
}
}
# Handle command line arguments
switch ($Action) {
"deploy" {
Start-MainDeployment
}
"rollback" {
Start-Rollback
}
"status" {
Show-Status
}
"logs" {
docker-compose logs -f
}
"stop" {
Write-Log "Stopping application..."
docker-compose down
Write-Log "Application stopped."
}
"restart" {
Write-Log "Restarting application..."
docker-compose restart
Write-Log "Application restarted."
}
default {
Write-Host "Usage: .\deploy.ps1 {deploy|rollback|status|logs|stop|restart}"
Write-Host ""
Write-Host "Commands:"
Write-Host " deploy - Deploy the application (default)"
Write-Host " rollback - Rollback to previous version"
Write-Host " status - Show deployment status"
Write-Host " logs - Show application logs"
Write-Host " stop - Stop the application"
Write-Host " restart - Restart the application"
}
}