#!/bin/bash # ============================================================================= # Deployment Script for Accessible Video Platform # ============================================================================= # This script handles building and deploying the application # Run from: /opt/video-accessibility/ # Usage: ./scripts/deploy.sh [options] # ============================================================================= set -e # Exit on any error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration PROJECT_DIR="/opt/video-accessibility" COMPOSE_FILES="-f docker-compose.yml -f docker-compose.prod.yml --env-file .env.production" # ============================================================================= # Helper Functions # ============================================================================= print_header() { echo -e "${BLUE}==============================================================================${NC}" echo -e "${BLUE}$1${NC}" echo -e "${BLUE}==============================================================================${NC}" } print_success() { echo -e "${GREEN} $1${NC}" } print_error() { echo -e "${RED} $1${NC}" } print_warning() { echo -e "${YELLOW}� $1${NC}" } print_info() { echo -e "${BLUE}9 $1${NC}" } # ============================================================================= # Pre-flight Checks # ============================================================================= preflight_checks() { print_header "Running Pre-flight Checks" # Check if running from correct directory if [ ! -f "docker-compose.yml" ]; then print_error "docker-compose.yml not found. Please run from /opt/video-accessibility/" exit 1 fi print_success "Running from correct directory" # Check if .env.production exists if [ ! -f ".env.production" ]; then print_error ".env.production not found. Please create it first." exit 1 fi print_success ".env.production found" # Check if secrets directory exists if [ ! -d "secrets" ]; then print_error "secrets/ directory not found. Please create it and add gcp-credentials.json" exit 1 fi print_success "secrets/ directory found" # Check if GCP credentials exist if [ ! -f "secrets/gcp-credentials.json" ]; then print_error "secrets/gcp-credentials.json not found" exit 1 fi print_success "GCP credentials found" # Check if Docker is running if ! docker info > /dev/null 2>&1; then print_error "Docker is not running" exit 1 fi print_success "Docker is running" # Check if docker compose is available if ! docker compose version &> /dev/null; then print_error "docker compose is not installed" exit 1 fi print_success "docker compose is available" echo "" } # ============================================================================= # Pull Latest Code # ============================================================================= pull_code() { print_header "Pulling Latest Code" if [ -d ".git" ]; then print_info "Pulling monorepo..." git pull origin main print_success "Code updated" elif [ -d "backend/.git" ]; then print_info "Pulling backend repository..." cd backend && git pull && cd .. print_success "Backend code updated" if [ -d "frontend/.git" ]; then print_info "Pulling frontend repository..." cd frontend && git pull && cd .. print_success "Frontend code updated" else print_warning "Frontend is not a git repository, skipping pull" fi else print_error "No git repository found. Cannot pull latest code." exit 1 fi echo "" } # ============================================================================= # Build and Deploy Backend # ============================================================================= deploy_backend() { print_header "Building and Deploying Backend Services" # Load environment variables export $(cat .env.production | grep -v '^#' | xargs) # Build images print_info "Building Docker images (this may take a few minutes)..." docker compose $COMPOSE_FILES build --no-cache print_success "Docker images built" # Stop existing containers print_info "Stopping existing containers..." docker compose $COMPOSE_FILES down print_success "Containers stopped" # Start services print_info "Starting services..." docker compose $COMPOSE_FILES up -d print_success "Services started" # Wait for services to be healthy print_info "Waiting for services to be healthy..." sleep 10 # Check service health if docker compose $COMPOSE_FILES ps | grep -q "unhealthy"; then print_error "Some services are unhealthy!" docker compose $COMPOSE_FILES ps exit 1 fi print_success "All services are healthy" echo "" } # ============================================================================= # Build and Deploy Frontend # ============================================================================= deploy_frontend() { print_header "Building and Deploying Frontend" cd frontend # Install dependencies (including dev deps needed for build) print_info "Installing frontend dependencies..." npm ci print_success "Dependencies installed" # Build frontend print_info "Building frontend..." npm run build print_success "Frontend built" # Deploy to Apache print_info "Deploying frontend to /var/www/html/video-accessibility/..." # Create directory if it doesn't exist sudo mkdir -p /var/www/html/video-accessibility # Copy built files sudo rm -rf /var/www/html/video-accessibility/* sudo cp -r dist/* /var/www/html/video-accessibility/ # Set proper permissions sudo chown -R www-data:www-data /var/www/html/video-accessibility sudo chmod -R 755 /var/www/html/video-accessibility print_success "Frontend deployed to Apache" cd .. echo "" } # ============================================================================= # Run Database Migrations # ============================================================================= run_migrations() { print_header "Running Database Migrations" print_info "Checking migration status..." docker compose $COMPOSE_FILES exec -T api python migrate.py status print_info "Applying pending migrations..." docker compose $COMPOSE_FILES exec -T api python migrate.py up print_success "Migrations completed" echo "" } # ============================================================================= # Display Status # ============================================================================= display_status() { print_header "Deployment Status" echo -e "${BLUE}Container Status:${NC}" docker compose $COMPOSE_FILES ps echo "" echo -e "${BLUE}Service URLs:${NC}" echo "Frontend: https://ai-sandbox.oliver.solutions/video-accessibility" echo "Backend API: https://ai-sandbox.oliver.solutions/video-accessibility-back" echo "API Health: https://ai-sandbox.oliver.solutions/video-accessibility-back/health" echo "" echo -e "${GREEN}Deployment completed successfully!${NC}" echo "" echo "To view logs:" echo " docker compose $COMPOSE_FILES logs -f [service]" echo "" echo "To restart a service:" echo " docker compose $COMPOSE_FILES restart [service]" echo "" } # ============================================================================= # Main Deployment Flow # ============================================================================= main() { print_header "Accessible Video Platform Deployment" echo "" # Run checks preflight_checks # Pull latest code if [ "$1" != "--skip-pull" ]; then pull_code fi # Deploy backend deploy_backend # Deploy frontend if [ "$1" != "--skip-frontend" ]; then deploy_frontend fi # Run migrations if [ "$1" != "--skip-migrations" ]; then run_migrations fi # Display status display_status } # Run main function main "$@"