#!/bin/bash # Docker entrypoint script for PPR API # Handles database migrations and data seeding automatically set -e echo "=========================================" echo "PPR API Container Starting" echo "=========================================" # Wait for database to be ready echo "Waiting for database to be ready..." python3 << EOF import sys import time from sqlalchemy import create_engine, text from app.core.config import settings max_retries = 30 retry_interval = 2 for i in range(max_retries): try: engine = create_engine(settings.database_url) with engine.connect() as conn: conn.execute(text("SELECT 1")) print("✓ Database is ready") sys.exit(0) except Exception as e: if i < max_retries - 1: print(f"Database not ready yet (attempt {i+1}/{max_retries}), waiting...") time.sleep(retry_interval) else: print(f"✗ Database connection failed after {max_retries} attempts: {e}") sys.exit(1) EOF if [ $? -ne 0 ]; then echo "Failed to connect to database. Exiting." exit 1 fi # Check if this is a fresh database or needs migration echo "" echo "Checking database state..." python3 << EOF import sys from sqlalchemy import create_engine, text, inspect from app.core.config import settings try: engine = create_engine(settings.database_url) inspector = inspect(engine) # Check if any tables exist tables = inspector.get_table_names() if not tables: print("✓ Fresh database detected - will initialize") sys.exit(2) # Signal fresh database elif 'alembic_version' not in tables: print("✓ Existing database without migration tracking - will stamp") sys.exit(3) # Signal existing database needs stamping else: print("✓ Database has migration tracking - will check for updates") sys.exit(0) # Normal migration check except Exception as e: print(f"✗ Error checking database: {e}") sys.exit(1) EOF DB_STATE=$? if [ $DB_STATE -eq 2 ]; then # Fresh database - run initial migration echo "" echo "Initializing fresh database..." cd /app alembic upgrade head echo "✓ Database schema created" # Seed reference data echo "" echo "Loading reference data..." python3 /app/seed_data.py echo "✓ Reference data loaded" elif [ $DB_STATE -eq 3 ]; then # Existing database without Alembic - stamp it echo "" echo "Stamping existing database with migration version..." cd /app alembic stamp head echo "✓ Database stamped" # Check if reference data exists python3 << EOF from sqlalchemy import create_engine, text from app.core.config import settings engine = create_engine(settings.database_url) with engine.connect() as conn: airport_count = conn.execute(text("SELECT COUNT(*) FROM airports")).fetchone()[0] aircraft_count = conn.execute(text("SELECT COUNT(*) FROM aircraft")).fetchone()[0] if airport_count == 0 or aircraft_count == 0: print("Reference data missing - will load") exit(10) else: print(f"Reference data exists (airports: {airport_count}, aircraft: {aircraft_count})") exit(0) EOF if [ $? -eq 10 ]; then echo "Loading reference data..." python3 /app/seed_data.py echo "✓ Reference data loaded" fi elif [ $DB_STATE -eq 0 ]; then # Database with Alembic tracking - check for pending migrations echo "" echo "Checking for pending migrations..." cd /app # Get current and head revisions CURRENT=$(alembic current 2>/dev/null | grep -o '[a-f0-9]\{12\}' | head -1 || echo "none") HEAD=$(alembic heads 2>/dev/null | grep -o '[a-f0-9]\{12\}' | head -1 || echo "none") if [ "$CURRENT" != "$HEAD" ] && [ "$HEAD" != "none" ]; then echo "✓ Pending migrations detected" echo " Current: $CURRENT" echo " Target: $HEAD" echo "Applying migrations..." alembic upgrade head echo "✓ Migrations applied" else echo "✓ Database is up to date" fi else echo "✗ Database check failed" exit 1 fi echo "" echo "=========================================" echo "Starting Application Server" echo "=========================================" echo "" # Start the application with appropriate settings if [ "${ENVIRONMENT}" = "production" ]; then echo "Starting in PRODUCTION mode with multiple workers..." exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers ${WORKERS:-4} else echo "Starting in DEVELOPMENT mode with auto-reload..." exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload fi