#!/bin/bash # ============================================================================= # Full Deployment Script for Accessible Video Platform # ============================================================================= # Rebuilds containers and deploys frontend # Run from: /opt/video-accessibility/ # # IMPORTANT: Run git pull BEFORE this script (as your user, not sudo): # cd /opt/video-accessibility # git pull origin main # cd backend && git pull origin main && cd .. # cd frontend && git pull origin main && cd .. # sudo ./scripts/full-deploy.sh # # Options: # --frontend-only Only build and deploy frontend (skip Docker rebuild) # ============================================================================= set -e # Exit on any error # Parse command line arguments FRONTEND_ONLY=false if [[ "$1" == "--frontend-only" ]]; then FRONTEND_ONLY=true fi # 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" FRONTEND_DEPLOY_DIR="/var/www/html/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 "Pre-flight Checks" # Check if running as root or with sudo if [ "$EUID" -ne 0 ]; then print_error "Please run with sudo" exit 1 fi print_success "Running with sudo" # Check if in correct directory if [ ! -f "docker-compose.yml" ]; then print_error "docker-compose.yml not found. Please run from $PROJECT_DIR" 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" 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" echo "" } # ============================================================================= # Verify Code is Up to Date # ============================================================================= verify_code_updated() { print_header "Verifying Code Status" print_warning "Make sure you ran 'git pull origin main' BEFORE running this script!" print_info "Git pull should be run as your user (not sudo) to use your SSH key" # Show last commit info as verification if [ -d ".git" ]; then print_info "Current commit (root):" git log -1 --oneline 2>/dev/null || print_warning "Could not read git log" fi if [ -d "backend/.git" ]; then print_info "Current commit (backend):" cd backend && git log -1 --oneline 2>/dev/null && cd .. || print_warning "Could not read backend git log" fi if [ -d "frontend/.git" ]; then print_info "Current commit (frontend):" cd frontend && git log -1 --oneline 2>/dev/null && cd .. || print_warning "Could not read frontend git log" fi echo "" } # ============================================================================= # Rebuild and Restart Containers # ============================================================================= rebuild_containers() { print_header "Rebuilding Docker Containers" # Load environment variables print_info "Loading environment variables from .env.production..." export $(cat .env.production | grep -v '^#' | xargs) print_info "Building images (this may take several minutes)..." docker compose $COMPOSE_FILES build --no-cache print_success "Docker images built" print_info "Stopping existing containers..." docker compose $COMPOSE_FILES down print_success "Containers stopped" print_info "Starting services..." docker compose $COMPOSE_FILES up -d print_success "Services started" print_info "Waiting for services to be healthy (30 seconds)..." sleep 30 # Check if containers are running print_info "Checking container status..." docker compose $COMPOSE_FILES ps # Check for unhealthy containers if docker compose $COMPOSE_FILES ps | grep -q "unhealthy"; then print_warning "Some services may be unhealthy, check logs" else print_success "All services appear healthy" fi echo "" } # ============================================================================= # Build and Deploy Frontend # ============================================================================= build_and_deploy_frontend() { print_header "Building and Deploying Frontend" cd frontend # Install dependencies print_info "Installing frontend dependencies..." npm ci print_success "Dependencies installed" # Build frontend print_info "Building React application..." npm run build print_success "Frontend build completed" # Check if build succeeded if [ ! -d "dist" ]; then print_error "Build failed - dist directory not found" exit 1 fi # Display build size BUILD_SIZE=$(du -sh dist | cut -f1) print_info "Build size: $BUILD_SIZE" cd .. # Deploy to Apache print_info "Deploying to $FRONTEND_DEPLOY_DIR..." # Clear and deploy print_info "Clearing deployment directory..." rm -rf "$FRONTEND_DEPLOY_DIR"/* print_success "Directory cleared" print_info "Copying build artifacts..." cp -r frontend/dist/* "$FRONTEND_DEPLOY_DIR"/ print_success "Files copied" # Set ownership and permissions print_info "Setting ownership to www-data..." chown -R www-data:www-data "$FRONTEND_DEPLOY_DIR" print_success "Ownership set" print_info "Setting permissions..." find "$FRONTEND_DEPLOY_DIR" -type d -exec chmod 755 {} \; find "$FRONTEND_DEPLOY_DIR" -type f -exec chmod 644 {} \; print_success "Permissions set" # Verify deployment if [ ! -f "$FRONTEND_DEPLOY_DIR/index.html" ]; then print_error "Deployment verification failed - index.html not found" exit 1 fi print_success "Deployment verified" 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 Deployment Summary # ============================================================================= display_summary() { print_header "Deployment Summary" echo -e "${BLUE}Container Status:${NC}" docker compose $COMPOSE_FILES ps echo "" echo -e "${GREEN} Deployment completed successfully!${NC}" 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 "${BLUE}Useful Commands:${NC}" echo " View logs: sudo docker compose $COMPOSE_FILES logs -f [service]" echo " Restart service: sudo docker compose $COMPOSE_FILES restart [service]" echo " Check status: sudo docker compose $COMPOSE_FILES ps" echo "" } # ============================================================================= # Main Deployment Flow # ============================================================================= main() { if [ "$FRONTEND_ONLY" = true ]; then print_header "Frontend-Only Deployment - Accessible Video Platform" echo "" echo "This script will:" echo " 1. Verify code status" echo " 2. Build and deploy frontend" echo "" echo "Docker containers will NOT be rebuilt (faster deployment)" echo "" echo -e "${YELLOW}REMINDER: You should have run 'git pull origin main' first!${NC}" echo "" # Confirm before proceeding read -p "Have you pulled the latest frontend code? Continue? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then print_warning "Deployment cancelled" exit 0 fi echo "" else print_header "Full Deployment - Accessible Video Platform" echo "" echo "This script will:" echo " 1. Verify code status" echo " 2. Rebuild all Docker containers" echo " 3. Restart all services" echo " 4. Build and deploy frontend" echo "" echo -e "${YELLOW}REMINDER: You should have run 'git pull origin main' first!${NC}" echo -e "${BLUE}TIP: Use --frontend-only flag to skip Docker rebuild${NC}" echo "" # Confirm before proceeding read -p "Have you pulled the latest code? Continue? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then print_warning "Deployment cancelled" exit 0 fi echo "" fi if [ "$FRONTEND_ONLY" = true ]; then # Frontend-only deployment preflight_checks verify_code_updated build_and_deploy_frontend print_header "Frontend Deployment Complete" echo -e "${GREEN}✓ Frontend deployed successfully!${NC}" echo "" echo "Frontend URL: https://ai-sandbox.oliver.solutions/video-accessibility" echo "" else # Full deployment preflight_checks verify_code_updated rebuild_containers run_migrations build_and_deploy_frontend display_summary fi print_success "Deployment complete! 🚀" } # Run main function main "$@"