codenuk_backend_mine/services/tech-stack-selector/docker-start.sh
2025-09-26 17:04:14 +05:30

306 lines
9.0 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ================================================================================================
# ENHANCED TECH STACK SELECTOR - DOCKER STARTUP SCRIPT
# Optimized for Docker environment with proper service discovery
# ================================================================================================
set -e
# Parse command line arguments
FORCE_MIGRATION=false
if [ "$1" = "--force-migration" ] || [ "$1" = "-f" ]; then
FORCE_MIGRATION=true
echo "🔄 Force migration mode enabled"
elif [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " --force-migration, -f Force re-run all migrations"
echo " --help, -h Show this help message"
echo ""
echo "Examples:"
echo " $0 # Normal startup with auto-migration detection"
echo " $0 --force-migration # Force re-run all migrations"
exit 0
fi
echo "="*60
echo "🚀 ENHANCED TECH STACK SELECTOR v15.0 - DOCKER VERSION"
echo "="*60
echo "✅ PostgreSQL data migrated to Neo4j"
echo "✅ Price-based relationships"
echo "✅ Real data from PostgreSQL"
echo "✅ Comprehensive pricing analysis"
echo "✅ Docker-optimized startup"
echo "="*60
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
# Get environment variables with defaults
POSTGRES_HOST=${POSTGRES_HOST:-postgres}
POSTGRES_PORT=${POSTGRES_PORT:-5432}
POSTGRES_USER=${POSTGRES_USER:-pipeline_admin}
POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-secure_pipeline_2024}
POSTGRES_DB=${POSTGRES_DB:-dev_pipeline}
NEO4J_URI=${NEO4J_URI:-bolt://neo4j:7687}
NEO4J_USER=${NEO4J_USER:-neo4j}
NEO4J_PASSWORD=${NEO4J_PASSWORD:-password}
CLAUDE_API_KEY=${CLAUDE_API_KEY:-}
print_status "Environment variables loaded"
print_info "PostgreSQL: ${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
print_info "Neo4j: ${NEO4J_URI}"
# Function to wait for service to be ready
wait_for_service() {
local service_name=$1
local host=$2
local port=$3
local max_attempts=30
local attempt=1
print_info "Waiting for ${service_name} to be ready..."
while [ $attempt -le $max_attempts ]; do
if nc -z $host $port 2>/dev/null; then
print_status "${service_name} is ready!"
return 0
fi
print_info "Attempt ${attempt}/${max_attempts}: ${service_name} not ready yet, waiting 2 seconds..."
sleep 2
attempt=$((attempt + 1))
done
print_error "${service_name} failed to become ready after ${max_attempts} attempts"
return 1
}
# Wait for PostgreSQL
if ! wait_for_service "PostgreSQL" $POSTGRES_HOST $POSTGRES_PORT; then
exit 1
fi
# Wait for Neo4j
if ! wait_for_service "Neo4j" neo4j 7687; then
exit 1
fi
# Function to check if database needs migration
check_database_migration() {
print_info "Checking if database needs migration..."
# Check if price_tiers table exists and has data
if ! python3 -c "
import psycopg2
import os
try:
conn = psycopg2.connect(
host=os.getenv('POSTGRES_HOST', 'postgres'),
port=int(os.getenv('POSTGRES_PORT', '5432')),
user=os.getenv('POSTGRES_USER', 'pipeline_admin'),
password=os.getenv('POSTGRES_PASSWORD', 'secure_pipeline_2024'),
database=os.getenv('POSTGRES_DB', 'dev_pipeline')
)
cursor = conn.cursor()
# Check if price_tiers table exists
cursor.execute(\"\"\"
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name = 'price_tiers'
);
\"\"\")
table_exists = cursor.fetchone()[0]
if not table_exists:
print('price_tiers table does not exist - migration needed')
exit(1)
# Check if price_tiers has data
cursor.execute('SELECT COUNT(*) FROM price_tiers;')
count = cursor.fetchone()[0]
if count == 0:
print('price_tiers table is empty - migration needed')
exit(1)
# Check if stack_recommendations has sufficient data
cursor.execute('SELECT COUNT(*) FROM stack_recommendations;')
rec_count = cursor.fetchone()[0]
if rec_count < 20: # Reduced threshold for Docker environment
print(f'stack_recommendations has only {rec_count} records - migration needed')
exit(1)
print('Database appears to be fully migrated')
cursor.close()
conn.close()
except Exception as e:
print(f'Error checking database: {e}')
exit(1)
" 2>/dev/null; then
return 1 # Migration needed
else
return 0 # Migration not needed
fi
}
# Function to run PostgreSQL migrations
run_postgres_migrations() {
print_info "Running PostgreSQL migrations..."
# Migration files in order
migration_files=(
"db/001_schema.sql"
"db/002_tools_migration.sql"
"db/003_tools_pricing_migration.sql"
)
# Set PGPASSWORD to avoid password prompts
export PGPASSWORD="$POSTGRES_PASSWORD"
for migration_file in "${migration_files[@]}"; do
if [ ! -f "$migration_file" ]; then
print_error "Migration file not found: $migration_file"
exit 1
fi
print_info "Running migration: $migration_file"
# Run migration with error handling
if psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -f "$migration_file" -q 2>/dev/null; then
print_status "Migration completed: $migration_file"
else
print_error "Migration failed: $migration_file"
print_info "Check the error logs above for details"
exit 1
fi
done
# Unset password
unset PGPASSWORD
print_status "All PostgreSQL migrations completed successfully"
}
# Check if migration is needed and run if necessary
if [ "$FORCE_MIGRATION" = true ]; then
print_warning "Force migration enabled - running migrations..."
run_postgres_migrations
# Verify migration was successful
print_info "Verifying migration..."
if check_database_migration; then
print_status "Migration verification successful"
else
print_error "Migration verification failed"
exit 1
fi
elif check_database_migration; then
print_status "Database is already migrated"
else
print_warning "Database needs migration - running migrations..."
run_postgres_migrations
# Verify migration was successful
print_info "Verifying migration..."
if check_database_migration; then
print_status "Migration verification successful"
else
print_error "Migration verification failed"
exit 1
fi
fi
# Check if Neo4j migration has been run
print_info "Checking if Neo4j migration has been completed..."
if ! python3 -c "
from neo4j import GraphDatabase
import os
try:
driver = GraphDatabase.driver(
os.getenv('NEO4J_URI', 'bolt://neo4j:7687'),
auth=(os.getenv('NEO4J_USER', 'neo4j'), os.getenv('NEO4J_PASSWORD', 'password'))
)
with driver.session() as session:
result = session.run('MATCH (p:PriceTier) RETURN count(p) as count')
price_tiers = result.single()['count']
if price_tiers == 0:
print('No data found in Neo4j - migration needed')
exit(1)
else:
print(f'Found {price_tiers} price tiers - migration appears complete')
driver.close()
except Exception as e:
print(f'Error checking migration status: {e}')
exit(1)
" 2>/dev/null; then
print_warning "No data found in Neo4j - running migration..."
# Run migration
if python3 migrate_postgres_to_neo4j.py; then
print_status "Migration completed successfully"
else
print_error "Migration failed"
exit 1
fi
else
print_status "Migration appears to be complete"
fi
# Set environment variables for the application
export NEO4J_URI="$NEO4J_URI"
export NEO4J_USER="$NEO4J_USER"
export NEO4J_PASSWORD="$NEO4J_PASSWORD"
export POSTGRES_HOST="$POSTGRES_HOST"
export POSTGRES_PORT="$POSTGRES_PORT"
export POSTGRES_USER="$POSTGRES_USER"
export POSTGRES_PASSWORD="$POSTGRES_PASSWORD"
export POSTGRES_DB="$POSTGRES_DB"
export CLAUDE_API_KEY="$CLAUDE_API_KEY"
print_status "Environment variables set"
# Create logs directory if it doesn't exist
mkdir -p logs
# Start the migrated application
print_info "Starting Enhanced Tech Stack Selector (Docker Version)..."
print_info "Server will be available at: http://localhost:8002"
print_info "API documentation: http://localhost:8002/docs"
print_info "Health check: http://localhost:8002/health"
print_info "Diagnostics: http://localhost:8002/api/diagnostics"
print_info ""
print_info "Press Ctrl+C to stop the server"
print_info ""
# Start the application
cd src
python3 main_migrated.py