Initial commit: Inventory Barcode System

This commit is contained in:
2025-07-22 20:24:51 -04:00
commit 511b01748d
63 changed files with 26932 additions and 0 deletions

View File

@ -0,0 +1,43 @@
#!/bin/bash
# Automated deployment script for Gitea webhook
# This script pulls the latest code and restarts the application
set -e
# Configuration
REPO_DIR="/path/to/your/inventory-barcode-system"
LOG_FILE="/var/log/inventory-deploy.log"
SERVICE_NAME="inventory-barcode-system"
# Logging function
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "Starting deployment..."
# Navigate to repository directory
cd "$REPO_DIR"
# Pull latest changes
log "Pulling latest changes from Gitea..."
git pull origin main
# Install/update dependencies
log "Installing dependencies..."
npm ci --only=production
# Restart the application
log "Restarting application..."
if command -v pm2 &> /dev/null; then
pm2 restart "$SERVICE_NAME" || pm2 start server.js --name "$SERVICE_NAME"
elif command -v systemctl &> /dev/null; then
sudo systemctl restart "$SERVICE_NAME"
else
# Kill existing process and start new one
pkill -f "node server.js" || true
nohup npm start > /dev/null 2>&1 &
fi
log "Deployment completed successfully!"

292
scripts/deploy.ps1 Normal file
View 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"
}
}

251
scripts/deploy.sh Normal file
View File

@ -0,0 +1,251 @@
#!/bin/bash
# Inventory Barcode System Deployment Script
# This script handles production deployment with Docker
set -e # Exit on any error
# 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"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Logging function
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
error() {
echo -e "${RED}[ERROR] $1${NC}"
echo "[ERROR] $1" >> "$LOG_FILE"
exit 1
}
warn() {
echo -e "${YELLOW}[WARNING] $1${NC}"
echo "[WARNING] $1" >> "$LOG_FILE"
}
# Check prerequisites
check_prerequisites() {
log "Checking prerequisites..."
# Check if Docker is installed
if ! command -v docker &> /dev/null; then
error "Docker is not installed. Please install Docker first."
fi
# Check if Docker Compose is installed
if ! command -v docker-compose &> /dev/null; then
error "Docker Compose is not installed. Please install Docker Compose first."
fi
# Check if .env file exists
if [ ! -f .env ]; then
warn ".env file not found. Creating from .env.example..."
if [ -f .env.example ]; then
cp .env.example .env
log "Please edit .env file with your configuration before continuing."
exit 0
else
error ".env.example file not found. Cannot create .env file."
fi
fi
log "Prerequisites check completed successfully."
}
# Create necessary directories
create_directories() {
log "Creating necessary directories..."
mkdir -p data/exports
mkdir -p data/backups
mkdir -p data/temp
mkdir -p logs
log "Directories created successfully."
}
# Backup existing database
backup_database() {
if [ -f "./inventory.db" ]; then
log "Backing up existing database..."
BACKUP_FILE="$BACKUP_DIR/pre-deployment-backup-$(date +%Y%m%d-%H%M%S).db"
mkdir -p "$BACKUP_DIR"
cp "./inventory.db" "$BACKUP_FILE"
log "Database backed up to: $BACKUP_FILE"
else
log "No existing database found. Skipping backup."
fi
}
# Build Docker image
build_image() {
log "Building Docker image..."
docker build -t "$DOCKER_IMAGE" .
if [ $? -eq 0 ]; then
log "Docker image built successfully."
else
error "Failed to build Docker image."
fi
}
# Stop existing container
stop_existing() {
log "Stopping existing container..."
if docker ps -q -f name="$CONTAINER_NAME" | grep -q .; then
docker stop "$CONTAINER_NAME"
docker rm "$CONTAINER_NAME"
log "Existing container stopped and removed."
else
log "No existing container found."
fi
}
# Deploy with Docker Compose
deploy() {
log "Deploying application with Docker Compose..."
# Pull latest images and start services
docker-compose down
docker-compose up -d
if [ $? -eq 0 ]; then
log "Application deployed successfully."
else
error "Failed to deploy application."
fi
}
# Health check
health_check() {
log "Performing health check..."
# Wait for application to start
sleep 10
# Check if container is running
if ! docker ps -q -f name="$APP_NAME" | grep -q .; then
error "Container is not running."
fi
# Check application health endpoint
local max_attempts=30
local attempt=1
while [ $attempt -le $max_attempts ]; do
if curl -f -s http://localhost:3000/health > /dev/null; then
log "Health check passed. Application is running."
return 0
fi
log "Health check attempt $attempt/$max_attempts failed. Retrying in 5 seconds..."
sleep 5
((attempt++))
done
error "Health check failed after $max_attempts attempts."
}
# Show deployment status
show_status() {
log "Deployment Status:"
echo ""
echo "Container Status:"
docker ps -f name="$APP_NAME"
echo ""
echo "Application Logs (last 20 lines):"
docker-compose logs --tail=20
echo ""
echo "Access the application at: http://localhost:3000"
echo "Health check endpoint: http://localhost:3000/health"
}
# Rollback function
rollback() {
warn "Rolling back deployment..."
# Stop current deployment
docker-compose down
# Restore database backup if exists
local latest_backup=$(ls -t "$BACKUP_DIR"/pre-deployment-backup-*.db 2>/dev/null | head -n1)
if [ -n "$latest_backup" ]; then
log "Restoring database from: $latest_backup"
cp "$latest_backup" "./inventory.db"
fi
warn "Rollback completed. Please check your previous deployment."
}
# Main deployment function
main() {
log "Starting deployment of $APP_NAME..."
# Trap errors and rollback
trap rollback ERR
check_prerequisites
create_directories
backup_database
build_image
stop_existing
deploy
health_check
show_status
log "Deployment completed successfully!"
}
# Handle command line arguments
case "${1:-deploy}" in
"deploy")
main
;;
"rollback")
rollback
;;
"status")
show_status
;;
"logs")
docker-compose logs -f
;;
"stop")
log "Stopping application..."
docker-compose down
log "Application stopped."
;;
"restart")
log "Restarting application..."
docker-compose restart
log "Application restarted."
;;
*)
echo "Usage: $0 {deploy|rollback|status|logs|stop|restart}"
echo ""
echo "Commands:"
echo " deploy - Deploy the application (default)"
echo " rollback - Rollback to previous version"
echo " status - Show deployment status"
echo " logs - Show application logs"
echo " stop - Stop the application"
echo " restart - Restart the application"
exit 1
;;
esac