#!/bin/bash set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' print_status() { echo -e "${BLUE}[INFO]${NC} $1"; } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } print_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Parse command line arguments FRESH_INSTALL=false if [[ "$1" == "--fresh" ]]; then FRESH_INSTALL=true fi # Configuration REMOTE_HOST="laantungir.net" REMOTE_USER="ubuntu" REMOTE_DIR="/home/ubuntu/ginxsom" REMOTE_DB_PATH="/home/ubuntu/ginxsom/db/ginxsom.db" REMOTE_NGINX_CONFIG="/etc/nginx/conf.d/default.conf" REMOTE_BINARY_PATH="/home/ubuntu/ginxsom/ginxsom.fcgi" REMOTE_SOCKET="/tmp/ginxsom-fcgi.sock" REMOTE_DATA_DIR="/var/www/html/blossom" print_status "Starting deployment to $REMOTE_HOST..." # Step 1: Build and prepare local binary print_status "Building ginxsom binary..." make clean && make if [[ ! -f "build/ginxsom-fcgi" ]]; then print_error "Build failed - binary not found" exit 1 fi print_success "Binary built successfully" # Step 2: Setup remote environment first (before copying files) print_status "Setting up remote environment..." ssh $REMOTE_USER@$REMOTE_HOST << 'EOF' set -e # Create data directory if it doesn't exist (using existing /var/www/html/blossom) sudo mkdir -p /var/www/html/blossom sudo chown www-data:www-data /var/www/html/blossom sudo chmod 755 /var/www/html/blossom # Ensure socket directory exists sudo mkdir -p /tmp sudo chmod 755 /tmp # Install required dependencies echo "Installing required dependencies..." sudo apt-get update sudo apt-get install -y spawn-fcgi libfcgi-dev # Stop any existing ginxsom processes echo "Stopping existing ginxsom processes..." sudo pkill -f ginxsom-fcgi || true sudo rm -f /tmp/ginxsom-fcgi.sock || true echo "Remote environment setup complete" EOF print_success "Remote environment configured" # Step 3: Copy files to remote server print_status "Copying files to remote server..." # Copy entire project directory (excluding unnecessary files) print_status "Copying entire ginxsom project..." rsync -avz --exclude='.git' --exclude='build' --exclude='logs' --exclude='Trash' --exclude='blobs' --exclude='db' --no-g --no-o --no-perms --omit-dir-times . $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ # Build on remote server to ensure compatibility print_status "Building ginxsom on remote server..." ssh $REMOTE_USER@$REMOTE_HOST "cd $REMOTE_DIR && make clean && make" || { print_error "Build failed on remote server" print_status "Checking what packages are actually installed..." ssh $REMOTE_USER@$REMOTE_HOST "dpkg -l | grep -E '(sqlite|fcgi)'" exit 1 } # Copy binary to application directory print_status "Copying ginxsom binary to application directory..." ssh $REMOTE_USER@$REMOTE_HOST << EOF # Stop any running process first sudo pkill -f ginxsom-fcgi || true sleep 1 # Remove old binary if it exists rm -f $REMOTE_BINARY_PATH # Copy new binary cp $REMOTE_DIR/build/ginxsom-fcgi $REMOTE_BINARY_PATH chmod +x $REMOTE_BINARY_PATH chown ubuntu:ubuntu $REMOTE_BINARY_PATH echo "Binary copied successfully" EOF # NOTE: Do NOT update nginx configuration automatically # The deployment script should only update ginxsom binaries and do nothing else with the system # Nginx configuration should be managed manually by the system administrator print_status "Skipping nginx configuration update (manual control required)" print_success "Files copied to remote server" # Step 3: Setup remote environment print_status "Setting up remote environment..." ssh $REMOTE_USER@$REMOTE_HOST << 'EOF' set -e # Create data directory if it doesn't exist (using existing /var/www/html/blossom) sudo mkdir -p /var/www/html/blossom sudo chown www-data:www-data /var/www/html/blossom sudo chmod 755 /var/www/html/blossom # Ensure socket directory exists sudo mkdir -p /tmp sudo chmod 755 /tmp # Install required dependencies echo "Installing required dependencies..." sudo apt-get update 2>/dev/null || true # Continue even if apt update has issues sudo apt-get install -y spawn-fcgi libfcgi-dev libsqlite3-dev sqlite3 libcurl4-openssl-dev # Verify installations echo "Verifying installations..." if ! dpkg -l libsqlite3-dev >/dev/null 2>&1; then echo "libsqlite3-dev not found, trying alternative..." sudo apt-get install -y libsqlite3-dev || { echo "Failed to install libsqlite3-dev" exit 1 } fi if ! dpkg -l libfcgi-dev >/dev/null 2>&1; then echo "libfcgi-dev not found" exit 1 fi # Check if sqlite3.h exists if [ ! -f /usr/include/sqlite3.h ]; then echo "sqlite3.h not found in /usr/include/" find /usr -name "sqlite3.h" 2>/dev/null || echo "sqlite3.h not found anywhere" exit 1 fi # Stop any existing ginxsom processes echo "Stopping existing ginxsom processes..." sudo pkill -f ginxsom-fcgi || true sudo rm -f /tmp/ginxsom-fcgi.sock || true echo "Remote environment setup complete" EOF print_success "Remote environment configured" # Step 4: Setup database directory and migrate database print_status "Setting up database directory..." ssh $REMOTE_USER@$REMOTE_HOST << EOF # Create db directory if it doesn't exist mkdir -p $REMOTE_DIR/db if [ "$FRESH_INSTALL" = "true" ]; then echo "Fresh install: removing existing database and blobs..." # Remove existing database sudo rm -f $REMOTE_DB_PATH sudo rm -f /var/www/html/blossom/ginxsom.db # Remove existing blobs sudo rm -rf $REMOTE_DATA_DIR/* echo "Existing data removed" else # Backup current database if it exists in old location if [ -f /var/www/html/blossom/ginxsom.db ]; then echo "Backing up existing database..." cp /var/www/html/blossom/ginxsom.db /var/www/html/blossom/ginxsom.db.backup.\$(date +%Y%m%d_%H%M%S) # Migrate database to new location if not already there if [ ! -f $REMOTE_DB_PATH ]; then echo "Migrating database to new location..." cp /var/www/html/blossom/ginxsom.db $REMOTE_DB_PATH else echo "Database already exists at new location" fi elif [ ! -f $REMOTE_DB_PATH ]; then echo "No existing database found - will be created on first run" else echo "Database already exists at $REMOTE_DB_PATH" fi fi # Set proper permissions - www-data needs write access to db directory for SQLite journal files sudo chown -R www-data:www-data $REMOTE_DIR/db sudo chmod 755 $REMOTE_DIR/db sudo chmod 644 $REMOTE_DB_PATH 2>/dev/null || true # Allow www-data to access the application directory for spawn-fcgi chdir chmod 755 $REMOTE_DIR echo "Database directory setup complete" EOF print_success "Database directory configured" # Step 5: Start ginxsom FastCGI process print_status "Starting ginxsom FastCGI process..." ssh $REMOTE_USER@$REMOTE_HOST << EOF # Clean up any existing socket sudo rm -f $REMOTE_SOCKET # Start FastCGI process with explicit paths echo "Starting ginxsom FastCGI with configuration:" echo " Working directory: $REMOTE_DIR" echo " Binary: $REMOTE_BINARY_PATH" echo " Database: $REMOTE_DB_PATH" echo " Storage: $REMOTE_DATA_DIR" sudo spawn-fcgi -M 666 -u www-data -g www-data -s $REMOTE_SOCKET -U www-data -G www-data -d $REMOTE_DIR -- $REMOTE_BINARY_PATH --db-path "$REMOTE_DB_PATH" --storage-dir "$REMOTE_DATA_DIR" # Give it a moment to start sleep 2 # Verify process is running if pgrep -f "ginxsom-fcgi" > /dev/null; then echo "FastCGI process started successfully" echo "PID: \$(pgrep -f ginxsom-fcgi)" else echo "Process not found by pgrep, but socket exists - this may be normal for FastCGI" echo "Checking socket..." ls -la $REMOTE_SOCKET echo "Checking if binary exists and is executable..." ls -la $REMOTE_BINARY_PATH echo "Testing if we can connect to the socket..." # Try to test the FastCGI connection if command -v cgi-fcgi >/dev/null 2>&1; then echo "Testing FastCGI connection..." SCRIPT_NAME=/health SCRIPT_FILENAME=$REMOTE_BINARY_PATH REQUEST_METHOD=GET cgi-fcgi -bind -connect $REMOTE_SOCKET 2>/dev/null | head -5 || echo "Connection test failed" else echo "cgi-fcgi not available for testing" fi # Don't exit - the socket existing means spawn-fcgi worked fi EOF if [ $? -eq 0 ]; then print_success "FastCGI process started" else print_error "Failed to start FastCGI process" exit 1 fi # Step 6: Test nginx configuration and reload print_status "Testing and reloading nginx..." ssh $REMOTE_USER@$REMOTE_HOST << 'EOF' # Test nginx configuration if sudo nginx -t; then echo "Nginx configuration test passed" sudo nginx -s reload echo "Nginx reloaded successfully" else echo "Nginx configuration test failed" exit 1 fi EOF print_success "Nginx reloaded" # Step 7: Test deployment print_status "Testing deployment..." # Test health endpoint echo "Testing health endpoint..." if curl -k -s --max-time 10 "https://blossom.laantungir.net/health" | grep -q "OK"; then print_success "Health check passed" else print_warning "Health check failed - checking response..." curl -k -v --max-time 10 "https://blossom.laantungir.net/health" 2>&1 | head -10 fi # Test basic endpoints echo "Testing root endpoint..." if curl -k -s --max-time 10 "https://blossom.laantungir.net/" | grep -q "Ginxsom"; then print_success "Root endpoint responding" else print_warning "Root endpoint not responding as expected - checking response..." curl -k -v --max-time 10 "https://blossom.laantungir.net/" 2>&1 | head -10 fi print_success "Deployment to $REMOTE_HOST completed!" print_status "Ginxsom should now be available at: https://blossom.laantungir.net" print_status "Test endpoints:" echo " Health: curl -k https://blossom.laantungir.net/health" echo " Root: curl -k https://blossom.laantungir.net/" echo " List: curl -k https://blossom.laantungir.net/list" if [ "$FRESH_INSTALL" = "true" ]; then print_warning "Fresh install completed - database and blobs have been reset" fi