#!/bin/bash # Exit on error set -e # Function to print error messages error() { echo -e "\e[31mERROR:\e[0m $1" >&2 exit 1 } # Function to print success messages success() { echo -e "\e[32mSUCCESS:\e[0m $1" } # Function to print info messages info() { echo -e "\e[34mINFO:\e[0m $1" } # Function to check if a command exists check_command() { if ! command -v "$1" &> /dev/null; then error "Required command '$1' not found. Please install it first." fi } # Function to compare version numbers version_compare() { if [[ "$1" == "$2" ]]; then echo 0 return fi local IFS=. local i ver1=($1) ver2=($2) # Fill empty positions in ver1 with zeros for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0 done for ((i=0; i<${#ver1[@]}; i++)); do # Fill empty positions in ver2 with zeros if [[ -z ${ver2[i]} ]]; then ver2[i]=0 fi if ((10#${ver1[i]} > 10#${ver2[i]})); then echo 1 return fi if ((10#${ver1[i]} < 10#${ver2[i]})); then echo -1 return fi done echo 0 } # Check for required system commands check_command python3 check_command pip3 # Check Python version PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))') MIN_VERSION="3.8" if [ $(version_compare "$PYTHON_VERSION" "$MIN_VERSION") -lt 0 ]; then error "Python version must be $MIN_VERSION or higher (found $PYTHON_VERSION)" fi success "Python version check passed (found $PYTHON_VERSION)" # Function to install packages on Fedora install_fedora_deps() { info "Installing Fedora dependencies..." # Check which packages need to be installed local packages=() local check_packages=( "python3-devel" "gcc" "python3-pip" "python3-setuptools" "python3-numpy" "python3-opencv" "python3-flask" "python3-gunicorn" "bc" "lsof" ) for pkg in "${check_packages[@]}"; do if ! rpm -q "$pkg" &>/dev/null; then packages+=("$pkg") fi done # Only run dnf if there are packages to install if [ ${#packages[@]} -gt 0 ]; then info "Installing missing packages: ${packages[*]}" sudo dnf install -y "${packages[@]}" || error "Failed to install required packages" else info "All required system packages are already installed" fi } # Function to install packages on Ubuntu/Debian install_ubuntu_deps() { info "Installing Ubuntu/Debian dependencies..." sudo apt-get update || error "Failed to update package lists" sudo apt-get install -y \ python3-dev \ python3-pip \ python3-venv \ python3-numpy \ python3-opencv \ python3-flask \ python3-gunicorn \ bc \ lsof \ || error "Failed to install required packages" } # Check and install system dependencies based on distribution install_system_deps() { if [ -f /etc/os-release ]; then . /etc/os-release case $ID in fedora) install_fedora_deps ;; ubuntu|debian) install_ubuntu_deps ;; *) info "Unknown distribution. Please ensure you have the following packages installed:" echo "- Python development package (python3-devel/python3-dev)" echo "- GCC compiler" echo "- Python pip" echo "- Python venv" echo "- Python numpy" echo "- Python OpenCV" echo "- Python Flask" echo "- Python Gunicorn" echo "- bc" echo "- lsof" ;; esac fi } # Install system dependencies install_system_deps # Create and activate virtual environment if [ ! -d "venv" ]; then info "Creating virtual environment..." # Create venv with system packages to use system numpy and opencv python3 -m venv venv --system-site-packages || error "Failed to create virtual environment" success "Virtual environment created successfully" fi # Ensure virtual environment is activated if [ -z "$VIRTUAL_ENV" ]; then info "Activating virtual environment..." source venv/bin/activate || error "Failed to activate virtual environment" fi # Upgrade pip to latest version info "Upgrading pip..." python3 -m pip install --upgrade pip setuptools wheel || error "Failed to upgrade pip and setuptools" # Create or update requirements.txt with compatible package versions if [ ! -f "requirements.txt" ]; then info "Creating requirements.txt..." cat > requirements.txt << EOF # Web framework and extensions Flask>=3.0.0 Flask-Cors>=4.0.0 Werkzeug>=3.0.0 gunicorn>=21.2.0 # Core dependencies opencv-python-headless>=4.8.0 # Flask dependencies click>=8.1.7 itsdangerous>=2.1.2 Jinja2>=3.1.2 MarkupSafe>=2.1.3 EOF success "Created requirements.txt" fi # Install requirements with better error handling info "Installing/updating requirements..." # First ensure pip is up to date pip install --upgrade pip # Install packages with specific options for better compatibility PYTHONWARNINGS="ignore" pip install \ --no-cache-dir \ --prefer-binary \ --only-binary :all: \ -r requirements.txt || error "Failed to install requirements" success "Requirements installed successfully" # Create necessary directories info "Creating required directories..." mkdir -p logs || error "Failed to create logs directory" success "Created required directories" # Function to check if port is available check_port() { if lsof -Pi :5000 -sTCP:LISTEN -t >/dev/null ; then error "Port 5000 is already in use. Please stop the other process first." fi } # Check if port is available check_port # Start Gunicorn with modern settings info "Starting server with Gunicorn..." exec gunicorn web_server:app \ --bind 0.0.0.0:5000 \ --workers $(nproc) \ --worker-class gthread \ --threads 2 \ --timeout 120 \ --access-logfile logs/access.log \ --error-logfile logs/error.log \ --capture-output \ --log-level info \ --reload \ --max-requests 1000 \ --max-requests-jitter 50 \ || error "Failed to start Gunicorn server"