Initial commit: Inventory Barcode System
This commit is contained in:
292
scripts/deploy.ps1
Normal file
292
scripts/deploy.ps1
Normal file
@ -0,0 +1,292 @@
|
||||
# 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"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user