#!/bin/bash # Configuration SERVER_USER="your_username" SERVER_IP="your_server_ip" APP_DIR="/path/to/your/app" PORT=5042 PYTHON_VERSION="3.11" WORKERS=4 THREADS=2 TIMEOUT=120 MAX_REQUESTS=1000 MAX_REQUESTS_JITTER=50 DEBUG_MODE=false # Set to true for verbose output # Colors for output GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Logging function log() { local level=$1 local message=$2 local timestamp=$(date '+%Y-%m-%d %H:%M:%S') case $level in "INFO") echo -e "${BLUE}[$timestamp] INFO: $message${NC}" ;; "SUCCESS") echo -e "${GREEN}[$timestamp] SUCCESS: $message${NC}" ;; "WARNING") echo -e "${YELLOW}[$timestamp] WARNING: $message${NC}" ;; "ERROR") echo -e "${RED}[$timestamp] ERROR: $message${NC}" ;; esac } # Debug logging function debug_log() { if [ "$DEBUG_MODE" = true ]; then echo -e "${YELLOW}[DEBUG] $1${NC}" fi } # Error handling set -e trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG trap 'if [ $? -ne 0 ]; then log "ERROR" "Command failed: $last_command"; exit 1; fi' EXIT log "INFO" "Starting deployment process..." # Check if required packages are installed log "INFO" "Checking required packages..." if ! command -v ssh &> /dev/null; then log "ERROR" "SSH is not installed. Please install it first." exit 1 fi # Create requirements.txt if it doesn't exist if [ ! -f "requirements.txt" ]; then log "INFO" "Creating requirements.txt..." echo "fastapi==0.109.2 uvicorn==0.27.1 gunicorn==21.2.0 python-dotenv==1.0.1 langchain-openai==0.0.5 requests==2.31.0 PyPDF2==3.0.1" > requirements.txt debug_log "Created requirements.txt with specific versions" fi # Create gunicorn config file log "INFO" "Creating Gunicorn configuration..." cat > gunicorn_config.py << EOL import multiprocessing import os # Server socket bind = "0.0.0.0:${PORT}" backlog = 2048 # Worker processes workers = ${WORKERS} worker_class = "uvicorn.workers.UvicornWorker" worker_connections = 1000 timeout = ${TIMEOUT} keepalive = 2 # Process naming proc_name = "firefighter" pythonpath = "." # Logging accesslog = "logs/access.log" errorlog = "logs/error.log" loglevel = "info" # Server mechanics daemon = False pidfile = "gunicorn.pid" umask = 0 user = None group = None tmp_upload_dir = None # SSL keyfile = None certfile = None # Server hooks def on_starting(server): pass def on_reload(server): pass def on_exit(server): pass # Worker lifecycle max_requests = ${MAX_REQUESTS} max_requests_jitter = ${MAX_REQUESTS_JITTER} graceful_timeout = 30 preload_app = True # Debug reload = False reload_engine = "auto" spew = False # Server mechanics check_config = False preload_app = True EOL debug_log "Created gunicorn_config.py with specified settings" # Copy files to server log "INFO" "Copying files to server..." debug_log "Using SCP to copy files to $SERVER_USER@$SERVER_IP:$APP_DIR/" scp -r ./* $SERVER_USER@$SERVER_IP:$APP_DIR/ # SSH into server and set up environment log "INFO" "Setting up environment on server..." ssh $SERVER_USER@$SERVER_IP << EOF set -e cd $APP_DIR # Install Python 3.11 if not present if ! command -v python${PYTHON_VERSION} &> /dev/null; then echo "Installing Python ${PYTHON_VERSION}..." sudo apt-get update sudo apt-get install -y software-properties-common sudo add-apt-repository -y ppa:deadsnakes/ppa sudo apt-get update sudo apt-get install -y python${PYTHON_VERSION} python${PYTHON_VERSION}-venv python${PYTHON_VERSION}-dev fi # Create virtual environment if it doesn't exist if [ ! -d "venv" ]; then python${PYTHON_VERSION} -m venv venv fi # Activate virtual environment and install dependencies source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt # Create systemd service file sudo tee /etc/systemd/system/firefighter.service << 'EOL' [Unit] Description=Fire Fighter Interview API After=network.target [Service] User=$SERVER_USER WorkingDirectory=$APP_DIR Environment="PATH=$APP_DIR/venv/bin" Environment="PYTHONPATH=$APP_DIR" ExecStart=$APP_DIR/venv/bin/gunicorn -c gunicorn_config.py app:app Restart=always RestartSec=5 StartLimitInterval=0 [Install] WantedBy=multi-user.target EOL # Create log directory mkdir -p logs # Reload systemd and start service sudo systemctl daemon-reload sudo systemctl enable firefighter sudo systemctl restart firefighter # Check service status sudo systemctl status firefighter EOF log "SUCCESS" "Deployment completed!" log "INFO" "Your application should now be running at http://$SERVER_IP:$PORT" log "INFO" "Check logs at $APP_DIR/logs/" # Print helpful commands echo -e "\n${BLUE}Useful commands:${NC}" echo "View service status: sudo systemctl status firefighter" echo "View logs: sudo journalctl -u firefighter -f" echo "Restart service: sudo systemctl restart firefighter" echo "Stop service: sudo systemctl stop firefighter"