← back to Watches
scripts/deploy.sh
252 lines
#!/bin/bash
###############################################################################
# Omega Watch Price History - Deployment Script
#
# Performs safe deployment with rollback capability
###############################################################################
set -euo pipefail
PROJECT_DIR="/root/Projects/watches"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DEPLOY_LOG="${PROJECT_DIR}/logs/deploy_${TIMESTAMP}.log"
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log() {
echo -e "${GREEN}[$(date +'%H:%M:%S')]${NC} $1" | tee -a "${DEPLOY_LOG}"
}
error() {
echo -e "${RED}[$(date +'%H:%M:%S')] ERROR:${NC} $1" | tee -a "${DEPLOY_LOG}" >&2
}
warning() {
echo -e "${YELLOW}[$(date +'%H:%M:%S')] WARNING:${NC} $1" | tee -a "${DEPLOY_LOG}"
}
info() {
echo -e "${BLUE}[$(date +'%H:%M:%S')] INFO:${NC} $1" | tee -a "${DEPLOY_LOG}"
}
# Pre-deployment checks
pre_deploy_checks() {
log "Running pre-deployment checks..."
# Check if port is available
if ! netstat -tuln | grep -q ":7600 "; then
warning "Service not currently running on port 7600"
fi
# Check disk space
local available_space=$(df -h /root | awk 'NR==2 {print $4}')
log "Available disk space: ${available_space}"
# Check if PM2 is running
if ! pm2 list | grep -q "online"; then
warning "No PM2 processes currently running"
fi
# Verify data integrity
if [ -f "${PROJECT_DIR}/data/watches.json" ]; then
if jq empty "${PROJECT_DIR}/data/watches.json" 2>/dev/null; then
log "✓ Data integrity check passed"
else
error "Data file is corrupted!"
exit 1
fi
else
error "Data file not found!"
exit 1
fi
log "Pre-deployment checks completed"
}
# Create backup before deployment
create_deployment_backup() {
log "Creating pre-deployment backup..."
"${PROJECT_DIR}/scripts/backup-system.sh" backup >> "${DEPLOY_LOG}" 2>&1
if [ $? -eq 0 ]; then
log "✓ Backup created successfully"
else
error "Backup failed!"
exit 1
fi
}
# Deploy application
deploy() {
log "=========================================="
log "Starting deployment: ${TIMESTAMP}"
log "=========================================="
cd "${PROJECT_DIR}"
# Git pull if repository exists
if [ -d ".git" ]; then
log "Pulling latest changes from repository..."
git pull origin main || warning "Git pull failed or no remote configured"
fi
# Install/update dependencies
log "Installing dependencies..."
npm ci --production >> "${DEPLOY_LOG}" 2>&1 || {
error "npm install failed"
exit 1
}
# Build frontend
log "Building frontend..."
npm run build >> "${DEPLOY_LOG}" 2>&1 || {
error "Build failed"
exit 1
}
# Reload PM2 process
log "Reloading PM2 process..."
pm2 reload ecosystem.config.js --update-env >> "${DEPLOY_LOG}" 2>&1 || {
error "PM2 reload failed"
return 1
}
# Wait for service to be ready
log "Waiting for service to start..."
sleep 5
# Health check
if health_check; then
log "✓ Deployment successful!"
pm2 save >> "${DEPLOY_LOG}" 2>&1
return 0
else
error "Health check failed after deployment"
return 1
fi
}
# Health check
health_check() {
local max_attempts=5
local attempt=1
while [ $attempt -le $max_attempts ]; do
log "Health check attempt ${attempt}/${max_attempts}..."
local http_code=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:7600/api/health)
if [ "$http_code" = "200" ]; then
log "✓ Health check passed (HTTP ${http_code})"
return 0
fi
warning "Health check failed (HTTP ${http_code}), retrying..."
sleep 3
((attempt++))
done
error "Health check failed after ${max_attempts} attempts"
return 1
}
# Rollback to previous version
rollback() {
error "=========================================="
error "INITIATING ROLLBACK"
error "=========================================="
log "Restoring from latest backup..."
local latest_backup=$(ls -t "${PROJECT_DIR}/backups/daily"/full_backup_*.tar.gz 2>/dev/null | head -1)
if [ -n "${latest_backup}" ]; then
"${PROJECT_DIR}/scripts/backup-system.sh" restore "${latest_backup}" >> "${DEPLOY_LOG}" 2>&1
if health_check; then
log "✓ Rollback successful"
return 0
else
error "Rollback failed - manual intervention required!"
return 1
fi
else
error "No backup found for rollback!"
return 1
fi
}
# Post-deployment tasks
post_deploy() {
log "Running post-deployment tasks..."
# Clear cache
curl -s -X POST http://localhost:7600/api/admin/clear-cache > /dev/null || true
# Log deployment
echo "${TIMESTAMP}: Deployment successful" >> "${PROJECT_DIR}/logs/deployments.log"
# Display service info
info "=========================================="
info "Deployment Summary"
info "=========================================="
info "Timestamp: ${TIMESTAMP}"
info "Service: http://45.61.58.125:7600"
info "Health: http://45.61.58.125:7600/api/health"
info "PM2 Status:"
pm2 list | grep -E "omega-watches|health-monitor" || true
info "=========================================="
}
# Main deployment flow
main() {
mkdir -p "${PROJECT_DIR}/logs"
log "Omega Watch Price History - Deployment Script"
log "Log file: ${DEPLOY_LOG}"
# Pre-deployment
pre_deploy_checks
create_deployment_backup
# Deploy
if deploy; then
post_deploy
log "🚀 Deployment completed successfully!"
exit 0
else
# Deployment failed, attempt rollback
if rollback; then
error "Deployment failed, but rollback successful"
exit 1
else
error "CRITICAL: Deployment AND rollback failed!"
error "Manual intervention required immediately"
exit 2
fi
fi
}
# Handle command line arguments
case "${1:-deploy}" in
deploy)
main
;;
rollback)
rollback
;;
health-check)
health_check
;;
*)
echo "Usage: $0 {deploy|rollback|health-check}"
exit 1
;;
esac