#!/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