#!/bin/bash # Deploy AI Tax Agent to Production Server # Usage: ./scripts/deploy-to-production.sh [step] # Steps: backup, prepare, infrastructure, services, monitoring, all set -e # Configuration REMOTE_HOST="deploy@141.136.35.199" REMOTE_PATH="/opt/ai-tax-agent" LOCAL_COMPOSE_PATH="infra/base" ENV_FILE="infra/environments/production/.env" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Helper functions log_info() { echo -e "${BLUE}ℹ️ $1${NC}" } log_success() { echo -e "${GREEN}✅ $1${NC}" } log_warning() { echo -e "${YELLOW}⚠️ $1${NC}" } log_error() { echo -e "${RED}❌ $1${NC}" } # Check prerequisites check_prerequisites() { log_info "Checking prerequisites..." if [ ! -f "$ENV_FILE" ]; then log_error "Production environment file not found: $ENV_FILE" log_info "Run: ./scripts/generate-production-secrets.sh" exit 1 fi if grep -q "CHANGE_ME" "$ENV_FILE"; then log_error "Production environment file contains CHANGE_ME placeholders" log_info "Run: ./scripts/generate-production-secrets.sh" exit 1 fi if ! command -v ssh &> /dev/null; then log_error "ssh command not found" exit 1 fi log_success "Prerequisites check passed" } # Backup remote server backup_remote() { log_info "Creating backup on remote server..." ssh $REMOTE_HOST << 'EOF' set -e mkdir -p ~/backups cd /opt # Backup application directory (exclude large cert files) if [ -d ai-tax-agent ]; then tar -czf ~/backups/backup-$(date +%Y%m%d-%H%M%S).tar.gz \ --exclude='./traefik/certs/godaddy-acme.json' \ --exclude='./*/node_modules' \ ai-tax-agent fi # Document current state docker ps > ~/backups/current-services-$(date +%Y%m%d-%H%M%S).txt docker volume ls > ~/backups/current-volumes-$(date +%Y%m%d-%H%M%S).txt echo "Backup created in ~/backups/" ls -lh ~/backups/ | tail -5 EOF log_success "Backup completed" } # Prepare remote server prepare_remote() { log_info "Preparing remote server directory structure..." ssh $REMOTE_HOST << EOF set -e # Create application directory mkdir -p $REMOTE_PATH # Create subdirectories for config files mkdir -p $REMOTE_PATH/prometheus mkdir -p $REMOTE_PATH/grafana/provisioning mkdir -p $REMOTE_PATH/grafana/dashboards mkdir -p $REMOTE_PATH/loki mkdir -p $REMOTE_PATH/promtail mkdir -p $REMOTE_PATH/traefik/config mkdir -p $REMOTE_PATH/authentik echo "Directory structure created" ls -la $REMOTE_PATH EOF log_success "Remote server prepared" } # Copy files to remote server copy_files() { log_info "Copying base compose files and configs to remote server..." # Copy compose files scp $LOCAL_COMPOSE_PATH/infrastructure.yaml $REMOTE_HOST:$REMOTE_PATH/ scp $LOCAL_COMPOSE_PATH/services.yaml $REMOTE_HOST:$REMOTE_PATH/ scp $LOCAL_COMPOSE_PATH/monitoring.yaml $REMOTE_HOST:$REMOTE_PATH/ # Copy environment file scp $ENV_FILE $REMOTE_HOST:$REMOTE_PATH/.env # Copy configuration files scp -r $LOCAL_COMPOSE_PATH/prometheus/* $REMOTE_HOST:$REMOTE_PATH/prometheus/ scp -r $LOCAL_COMPOSE_PATH/grafana/provisioning/* $REMOTE_HOST:$REMOTE_PATH/grafana/provisioning/ scp -r $LOCAL_COMPOSE_PATH/grafana/dashboards/* $REMOTE_HOST:$REMOTE_PATH/grafana/dashboards/ scp -r $LOCAL_COMPOSE_PATH/loki/* $REMOTE_HOST:$REMOTE_PATH/loki/ scp -r $LOCAL_COMPOSE_PATH/promtail/* $REMOTE_HOST:$REMOTE_PATH/promtail/ 2>/dev/null || true scp -r $LOCAL_COMPOSE_PATH/traefik/config/* $REMOTE_HOST:$REMOTE_PATH/traefik/config/ 2>/dev/null || true scp -r $LOCAL_COMPOSE_PATH/authentik/* $REMOTE_HOST:$REMOTE_PATH/authentik/ 2>/dev/null || true log_success "Files copied to remote server" } # Deploy infrastructure deploy_infrastructure() { log_info "Deploying infrastructure services..." ssh $REMOTE_HOST << EOF set -e cd $REMOTE_PATH echo "Starting infrastructure services..." docker compose -f infrastructure.yaml up -d echo "Waiting for services to be healthy..." sleep 30 echo "Infrastructure services status:" docker compose -f infrastructure.yaml ps EOF log_success "Infrastructure deployed" } # Deploy services deploy_services() { log_info "Deploying application services..." ssh $REMOTE_HOST << EOF set -e cd $REMOTE_PATH echo "Pulling latest images..." docker compose -f services.yaml pull || true echo "Starting application services..." docker compose -f services.yaml up -d echo "Waiting for services to start..." sleep 20 echo "Application services status:" docker compose -f services.yaml ps EOF log_success "Application services deployed" } # Deploy monitoring deploy_monitoring() { log_info "Deploying monitoring stack..." ssh $REMOTE_HOST << EOF set -e cd $REMOTE_PATH echo "Starting monitoring services..." docker compose -f monitoring.yaml up -d echo "Waiting for services to start..." sleep 15 echo "Monitoring services status:" docker compose -f monitoring.yaml ps EOF log_success "Monitoring stack deployed" } # Verify deployment verify_deployment() { log_info "Verifying deployment..." ssh $REMOTE_HOST << EOF set -e cd $REMOTE_PATH echo "=== Infrastructure Services ===" docker compose -f infrastructure.yaml ps echo "" echo "=== Application Services ===" docker compose -f services.yaml ps echo "" echo "=== Monitoring Services ===" docker compose -f monitoring.yaml ps echo "" echo "=== Docker Networks ===" docker network ls | grep -E "apa-frontend|apa-backend" echo "" echo "=== Disk Usage ===" df -h | grep -E "Filesystem|/dev/sda" EOF log_success "Deployment verification completed" } # Show logs show_logs() { local service=$1 log_info "Showing logs for $service..." ssh $REMOTE_HOST << EOF cd $REMOTE_PATH docker compose -f services.yaml logs --tail=50 $service EOF } # Main deployment flow deploy_all() { log_info "Starting full deployment to production..." check_prerequisites backup_remote prepare_remote copy_files deploy_infrastructure log_warning "Infrastructure deployed. Please verify services are healthy before continuing." read -p "Continue with application deployment? (y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then log_warning "Deployment paused. Run './scripts/deploy-to-production.sh services' to continue." exit 0 fi deploy_services deploy_monitoring verify_deployment log_success "🎉 Deployment completed successfully!" log_info "Access your services at:" echo " - Application: https://app.harkon.co.uk" echo " - API: https://api.harkon.co.uk" echo " - Grafana: https://grafana.harkon.co.uk" echo " - Vault: https://vault.harkon.co.uk" } # Parse command line arguments case "${1:-all}" in backup) backup_remote ;; prepare) check_prerequisites prepare_remote copy_files ;; infrastructure) deploy_infrastructure ;; services) deploy_services ;; monitoring) deploy_monitoring ;; verify) verify_deployment ;; logs) show_logs "${2:-apa-svc-ingestion}" ;; all) deploy_all ;; *) echo "Usage: $0 {backup|prepare|infrastructure|services|monitoring|verify|logs|all}" echo "" echo "Steps:" echo " backup - Create backup of remote server" echo " prepare - Prepare remote server and copy files" echo " infrastructure - Deploy infrastructure services" echo " services - Deploy application services" echo " monitoring - Deploy monitoring stack" echo " verify - Verify deployment status" echo " logs [service] - Show logs for a service" echo " all - Run full deployment (default)" exit 1 ;; esac