#!/bin/bash ################################################################################ # Nginx + Varnish + Apache Caching Manager for cPanel ################################################################################ # Purpose: Complete setup and management of Nginx → Varnish → Apache stack # Architecture: Client → Nginx (80/443) → Varnish (6081) → Apache (81/444) # Stock Approach: Uses cPanel's ea-nginx + Apache on default ports # Only modifies Nginx proxy target (81 → 6081) # Features: # - Full automated setup with domain testing # - Revert/rollback functionality # - Self-healing diagnostics and auto-fix # - Smart memory allocation based on server resources # - Configuration health checks # - Backup/restore of all configurations # - cPanel hook for auto-recovery after updates ################################################################################ set -eo pipefail # Path resolution SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" source "$SCRIPT_DIR/lib/common-functions.sh" source "$SCRIPT_DIR/lib/system-detect.sh" source "$SCRIPT_DIR/lib/reference-db.sh" # Root check if [ "$EUID" -ne 0 ]; then print_error "This script must be run as root" exit 1 fi # Configuration BACKUP_DIR="/root/nginx-varnish-backups" VARNISH_VCL="/etc/varnish/default.vcl" VARNISH_SERVICE="/usr/lib/systemd/system/varnish.service" VARNISH_PORT="6081" # Varnish default port (stock) APACHE_HTTP_PORT="81" # ea-nginx stock port (unchanged) APACHE_HTTPS_PORT="444" # ea-nginx stock SSL port (unchanged) NGINX_VENDOR_CONF="/etc/nginx/conf.d/includes-optional/cpanel-proxy-vendors/varnish-proxy.conf" NGINX_CONFIG_SCRIPT="/etc/nginx/ea-nginx/config-scripts/global/varnish-integration.sh" # Status indicators STATUS_FILE="/root/.nginx-varnish-status" HOOK_SCRIPT="/root/nginx-varnish-hook.sh" HOOK_LOG="/var/log/nginx-varnish-hook.log" ################################################################################ # HELPER FUNCTIONS ################################################################################ # Check if cPanel Nginx is installed check_nginx_installed() { if rpm -q ea-nginx >/dev/null 2>&1; then return 0 else return 1 fi } # Check if Varnish is installed check_varnish_installed() { if rpm -q varnish >/dev/null 2>&1; then return 0 else return 1 fi } # Check if setup is already configured check_if_configured() { if [ -f "$STATUS_FILE" ] && grep -q "CONFIGURED=yes" "$STATUS_FILE" 2>/dev/null; then return 0 else return 1 fi } # Get total system RAM in MB get_total_ram_mb() { free -m | awk '/^Mem:/{print $2}' } # Calculate recommended Varnish memory calculate_varnish_memory() { local total_ram=$(get_total_ram_mb) local varnish_mem # Allocate 10-20% of total RAM for Varnish, with sensible limits if [ "$total_ram" -lt 2048 ]; then # Less than 2GB RAM - use 256MB varnish_mem=256 elif [ "$total_ram" -lt 4096 ]; then # 2-4GB RAM - use 512MB varnish_mem=512 elif [ "$total_ram" -lt 8192 ]; then # 4-8GB RAM - use 1GB varnish_mem=1024 elif [ "$total_ram" -lt 16384 ]; then # 8-16GB RAM - use 2GB varnish_mem=2048 else # 16GB+ RAM - use 4GB varnish_mem=4096 fi echo "$varnish_mem" } # Create backup with timestamp create_backup() { local timestamp=$(date +%Y%m%d_%H%M%S) local backup_path="$BACKUP_DIR/backup_$timestamp" # Check disk space before backup local available_space=$(df /root | tail -1 | awk '{print $4}') if [ "$available_space" -lt 51200 ]; then print_error "Insufficient disk space for backup (less than 50MB available)" return 1 fi mkdir -p "$backup_path" # Backup Nginx configs if they exist if [ -f /etc/nginx/ea-nginx.conf ]; then cp -a /etc/nginx/ea-nginx.conf "$backup_path/" 2>/dev/null || true fi if [ -d /etc/nginx/conf.d ]; then cp -a /etc/nginx/conf.d "$backup_path/" 2>/dev/null || true fi if [ -d /etc/nginx/ea-nginx ]; then cp -a /etc/nginx/ea-nginx "$backup_path/" 2>/dev/null || true fi # Backup Varnish configs if they exist if [ -f /etc/varnish/default.vcl ]; then cp -a /etc/varnish/default.vcl "$backup_path/" 2>/dev/null || true fi if [ -f /usr/lib/systemd/system/varnish.service ]; then cp -a /usr/lib/systemd/system/varnish.service "$backup_path/" 2>/dev/null || true fi # Backup Apache configs if [ -f /var/cpanel/cpanel.config ]; then cp -a /var/cpanel/cpanel.config "$backup_path/" 2>/dev/null || true fi echo "$backup_path" } # Get list of cPanel domains get_cpanel_domains() { local domains=() # Get domains from cPanel user data if [ -d /var/cpanel/userdata ]; then while IFS= read -r domain_file; do local domain=$(basename "$domain_file") # Skip cache files, main file, and config files if [[ "$domain_file" =~ \.cache$ ]] || \ [[ "$domain_file" =~ /cache$ ]] || \ [[ "$domain_file" =~ /main$ ]] || \ [[ "$domain" =~ _SSL$ ]] || \ [[ "$domain" =~ \.yaml$ ]] || \ [[ "$domain" =~ \.json$ ]] || \ [[ "$domain" =~ \.conf$ ]] || \ [[ "$domain" =~ \.backup$ ]]; then continue fi # Only add if it looks like a domain (has a dot, not . or ..) if [[ "$domain" != "." && "$domain" != ".." && "$domain" =~ \. ]]; then domains+=("$domain") fi done < <(find /var/cpanel/userdata -type f 2>/dev/null | head -20) fi printf '%s\n' "${domains[@]}" } # Check if cPanel hook is registered check_hook_registered() { if [ -f /usr/local/cpanel/bin/manage_hooks ]; then if /usr/local/cpanel/bin/manage_hooks list 2>/dev/null | grep -q "nginx-varnish-hook.sh"; then return 0 fi fi return 1 } # Modify ea-nginx settings.json to use Varnish port modify_settings_json() { local settings_file="/etc/nginx/ea-nginx/settings.json" print_info "Modifying ea-nginx settings.json to use Varnish port..." # Backup original settings.json if [ ! -f "${settings_file}.stock" ]; then cp "$settings_file" "${settings_file}.stock" print_info "Original settings.json backed up to ${settings_file}.stock" fi # ============================================================================ # HTTP + HTTPS Caching Configuration # ============================================================================ # Strategy: SSL termination at Nginx, HTTP backends to Varnish # # How it works: # 1. settings.json sets apache_port to 6081 (Varnish) for HTTP traffic # 2. ea-nginx generates config with $scheme://apache_backend_${scheme}_... # 3. Config-script post-processes to force HTTP protocol for all backends # 4. Result: SSL terminates at Nginx, all backend traffic uses HTTP to Varnish # # Architecture: # - Client → Nginx (SSL termination for HTTPS) → Varnish → Apache (all HTTP) # - HTTP: Client:80 → Nginx:80 → Varnish:6081 → Apache:81 [CACHED] # - HTTPS: Client:443 → Nginx:443 (SSL) → Varnish:6081 (HTTP) → Apache:81 [CACHED] # # Note: Config-script at /etc/nginx/ea-nginx/config-scripts/global/ runs after # every ea-nginx rebuild to maintain the HTTP backend override. # ============================================================================ cat > "$settings_file" < "$settings_file" < "$config_script" <<'EOFSCRIPT' #!/bin/bash ################################################################################ # ea-nginx Global Config Script: Varnish Proxy Auto-Fix ################################################################################ # Purpose: Automatically re-apply Varnish proxy configuration after ea-nginx # config regeneration (runs every time ea-nginx config --global runs) # Location: /etc/nginx/ea-nginx/config-scripts/global/ # Triggered by: ea-nginx config --global, ea-nginx config --all, cPanel updates ################################################################################ NGINX_CONF="/etc/nginx/conf.d/ea-nginx.conf" STATUS_FILE="/root/.nginx-varnish-status" LOG_FILE="/var/log/nginx-varnish-hook.log" # Logging function log_message() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ea-nginx-config-script] $1" >> "$LOG_FILE" } log_message "=== ea-nginx Config Script Triggered ===" # Check if Varnish integration is configured if [ ! -f "$STATUS_FILE" ] || ! grep -q "CONFIGURED=yes" "$STATUS_FILE" 2>/dev/null; then log_message "Varnish not configured. Skipping." exit 0 fi log_message "Varnish integration detected. Checking Nginx configuration..." # Check if nginx conf exists if [ ! -f "$NGINX_CONF" ]; then log_message "ERROR: Nginx config file not found at $NGINX_CONF" exit 0 fi # Check if configuration needs fixing (ea-nginx regenerated it to stock port 81) if grep -q "^\s*default\s\+81\s*;" "$NGINX_CONF" 2>/dev/null; then log_message "DETECTED: ea-nginx.conf regenerated with stock port 81. Re-applying Varnish proxy (port 6081)..." # Re-apply proxy port change to Varnish if sed -i 's/^\(\s*default\s\+\)81\s*;/\16081;/' "$NGINX_CONF" 2>/dev/null; then log_message "SUCCESS: Proxy port changed to 6081 (Varnish)" else log_message "ERROR: Failed to change proxy port to 6081" fi else log_message "Configuration already correct (points to port 6081). No action needed." fi log_message "=== Config Script Completed ===" exit 0 EOFSCRIPT chmod +x "$config_script" if [ -f "$config_script" ] && [ -x "$config_script" ]; then print_success "ea-nginx config script created successfully" print_info "Script will auto-fix proxy port after ANY ea-nginx rebuild" return 0 else print_error "Failed to create ea-nginx config script" return 1 fi } # Remove ea-nginx config script remove_eanginx_config_script() { local config_script="/etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish" if [ -f "$config_script" ]; then print_info "Removing ea-nginx config script..." rm -f "$config_script" print_success "ea-nginx config script removed" fi return 0 } ################################################################################ # INSTALLATION FUNCTIONS ################################################################################ # Install cPanel Nginx install_cpanel_nginx() { print_banner "Installing cPanel Nginx" # Fix hostname resolution for Apache RemoteIPInternalProxy local server_hostname=$(hostname -f 2>/dev/null || hostname) if [ -n "$server_hostname" ]; then if ! grep -q "127.0.0.1.*$server_hostname" /etc/hosts 2>/dev/null; then echo "Adding hostname to /etc/hosts for Apache configuration..." echo "127.0.0.1 $server_hostname" >> /etc/hosts print_info "Added $server_hostname to /etc/hosts" fi fi echo "" echo "Installing ea-nginx package..." if yum install -y ea-nginx; then print_success "ea-nginx installed successfully" else print_error "Failed to install ea-nginx" return 1 fi echo "" echo "Rebuilding HTTP configuration..." if /scripts/rebuildhttpdconf; then print_success "HTTP configuration rebuilt" else print_error "Failed to rebuild HTTP configuration" return 1 fi echo "" echo "Enabling and starting Nginx..." systemctl enable nginx systemctl restart nginx if systemctl is-active --quiet nginx; then print_success "Nginx is running" else print_error "Nginx failed to start" return 1 fi return 0 } # Install Varnish install_varnish() { print_banner "Installing Varnish Cache" echo "Installing Varnish 6.6 from AlmaLinux repositories..." echo "(Varnish 6.6 with VCL 4.1 support is fully compatible)" echo "" if yum install -y varnish; then local varnish_version=$(varnishd -V 2>&1 | head -1) print_success "Varnish installed successfully" echo " Version: $varnish_version" else print_error "Failed to install Varnish" return 1 fi systemctl enable varnish return 0 } # Configure Varnish VCL configure_varnish_vcl() { print_banner "Configuring Varnish VCL" # Simple VCL with comprehensive admin page bypasses cat > "$VARNISH_VCL" <<'EOFVCL' vcl 4.1; # Backend definition - Apache on port 81 (ea-nginx stock port) backend default { .host = "127.0.0.1"; .port = "81"; .connect_timeout = 600s; .first_byte_timeout = 600s; .between_bytes_timeout = 600s; } sub vcl_recv { # Normalize the host header set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); # CRITICAL: AutoSSL / Let's Encrypt - Don't cache SSL validation if (req.url ~ "^/\.well-known/acme-challenge/") { return (pass); } # CRITICAL: cPanel Services - Don't cache cPanel admin interfaces if (req.http.Host ~ "^(cpanel|webmail|whm|cpcalendars|cpcontacts)\." || req.http.Host ~ ":2082$" || req.http.Host ~ ":2083$" || req.http.Host ~ ":2086$" || req.http.Host ~ ":2087$") { return (pipe); } # Don't cache admin/login pages for common CMSs and admin panels if (req.url ~ "^/wp-admin" || req.url ~ "^/wp-login\.php" || req.url ~ "^/administrator" || req.url ~ "^/admin" || req.url ~ "^/user/login" || req.url ~ "^/cpanel" || req.url ~ "^/webmail" || req.url ~ "^/whm" || req.url ~ "^/phpmyadmin" || req.url ~ "^/pma" || req.url ~ "^/roundcube" || req.url ~ "^/horde" || req.url ~ "^/squirrelmail") { return (pass); } # Don't cache POST requests if (req.method == "POST") { return (pass); } # Don't cache requests with cookies (except static files) if (req.http.Cookie && req.url !~ "\.(jpg|jpeg|jpe|gif|png|ico|bmp|tif|tiff|svg|svgz|webp|avif|heic|heif|jfif|pjpeg|pjp|apng|css|js|mjs|map|woff|woff2|ttf|otf|eot|zip|tgz|gz|tar|rar|bz2|7z|xz|lz|lzma|pdf|txt|rtf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|csv|xml|json|mp3|mp4|m4a|m4v|ogg|oga|ogv|webm|wav|flac|aac|wma|opus|mid|midi|avi|mov|wmv|flv|mkv|mpeg|mpg|3gp|3g2|m2v|ts|m3u8|swf|html|htm|wasm|manifest|appcache|bin|exe|msi|dmg|iso|deb|rpm|cab)$") { return (pass); } # Cache static files - remove cookies if (req.url ~ "\.(jpg|jpeg|jpe|gif|png|ico|bmp|tif|tiff|svg|svgz|webp|avif|heic|heif|jfif|pjpeg|pjp|apng|css|js|mjs|map|woff|woff2|ttf|otf|eot|zip|tgz|gz|tar|rar|bz2|7z|xz|lz|lzma|pdf|txt|rtf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|csv|xml|json|mp3|mp4|m4a|m4v|ogg|oga|ogv|webm|wav|flac|aac|wma|opus|mid|midi|avi|mov|wmv|flv|mkv|mpeg|mpg|3gp|3g2|m2v|ts|m3u8|swf|html|htm|wasm|manifest|appcache|bin|exe|msi|dmg|iso|deb|rpm|cab)$") { unset req.http.Cookie; return (hash); } # Default: try to serve from cache return (hash); } sub vcl_backend_fetch { # CRITICAL: Preserve Host header for Apache VirtualHost routing # Without this, Apache receives IP address and serves wrong VirtualHost if (bereq.http.Host) { set bereq.http.Host = bereq.http.Host; } } sub vcl_backend_response { # Add identifying header set beresp.http.X-Served-By = "Varnish"; # Cache static files for 1 hour if (bereq.url ~ "\.(jpg|jpeg|jpe|gif|png|ico|bmp|tif|tiff|svg|svgz|webp|avif|heic|heif|jfif|pjpeg|pjp|apng|css|js|mjs|map|woff|woff2|ttf|otf|eot|zip|tgz|gz|tar|rar|bz2|7z|xz|lz|lzma|pdf|txt|rtf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|csv|xml|json|mp3|mp4|m4a|m4v|ogg|oga|ogv|webm|wav|flac|aac|wma|opus|mid|midi|avi|mov|wmv|flv|mkv|mpeg|mpg|3gp|3g2|m2v|ts|m3u8|swf|html|htm|wasm|manifest|appcache|bin|exe|msi|dmg|iso|deb|rpm|cab)$") { set beresp.ttl = 1h; unset beresp.http.Set-Cookie; } # Don't cache if Set-Cookie is present (dynamic content) if (beresp.http.Set-Cookie) { set beresp.ttl = 0s; set beresp.uncacheable = true; return (deliver); } # Cache 404s for a short time to reduce backend load if (beresp.status == 404) { set beresp.ttl = 60s; } # Don't cache 5xx errors if (beresp.status >= 500) { set beresp.ttl = 0s; set beresp.uncacheable = true; return (deliver); } return (deliver); } sub vcl_deliver { # Add cache status header for debugging if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; set resp.http.X-Cache-Hits = obj.hits; } else { set resp.http.X-Cache = "MISS"; } # Keep the Varnish identifier set resp.http.X-Served-By = "Varnish"; # Remove internal headers before sending to client unset resp.http.X-Varnish; unset resp.http.Via; unset resp.http.Age; return (deliver); } EOFVCL # Test VCL configuration # Note: /tmp is usually mounted with noexec on cPanel servers, so use -n parameter # to specify a working directory outside /tmp mkdir -p /var/lib/varnish/test if varnishd -n /var/lib/varnish/test -C -f "$VARNISH_VCL" >/dev/null 2>&1; then print_success "VCL configuration is valid" return 0 else print_error "VCL configuration is invalid" return 1 fi } # Configure Varnish to listen on port 81 configure_varnish_port() { local varnish_mem="${1:-256}" print_banner "Configuring Varnish Port and Memory" echo "Setting Varnish to listen on port $VARNISH_PORT with ${varnish_mem}m RAM..." # Create systemd override directory mkdir -p /etc/systemd/system/varnish.service.d/ # Create override configuration cat > /etc/systemd/system/varnish.service.d/override.conf </dev/null 2>&1; then print_success "ea-nginx configuration rebuilt" else print_warning "ea-nginx rebuild encountered issues (may still work)" fi # Verify the generated config local nginx_conf="/etc/nginx/conf.d/ea-nginx.conf" if grep -q "default 6081;" "$nginx_conf" 2>/dev/null; then print_success "Nginx configured to proxy to Varnish (port 6081)" else print_warning "Proxy port may not be correct - check ea-nginx.conf" fi # Test Nginx configuration if nginx -t >/dev/null 2>&1; then print_success "Nginx configuration is valid" return 0 else print_error "Nginx configuration test failed" nginx -t 2>&1 | tail -5 return 1 fi } # Test domain accessibility test_domain() { local domain="$1" local protocol="$2" local url="${protocol}://${domain}" local response=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$url" 2>/dev/null || echo "000") local varnish_header=$(curl -s -I --max-time 5 "$url" 2>/dev/null | grep -i "X-Served-By" | grep -i "Varnish" || true) if [ "$response" = "200" ] || [ "$response" = "301" ] || [ "$response" = "302" ]; then if [ -n "$varnish_header" ]; then echo "✓ $domain ($protocol): $response - Varnish active" return 0 else echo "⚠ $domain ($protocol): $response - No Varnish header" return 0 # Don't crash the script fi else echo "✗ $domain ($protocol): $response" return 1 fi } # Quick proof that caching is actually working proof_of_caching() { print_banner "Proof of Caching Test" echo "This test proves caching is working by showing MISS → HIT pattern" echo "" # Get first domain local domain=$(get_cpanel_domains | head -1) if [ -z "$domain" ]; then print_error "No domains found to test" return 0 fi echo "Testing domain: $domain" echo "" # Test common static files local test_files=( "/favicon.ico" "/robots.txt" "/" ) local cache_working=0 for test_path in "${test_files[@]}"; do local url="http://${domain}${test_path}" echo "Testing: $test_path" # First request - should be MISS local first_request=$(curl -s -I --max-time 5 "$url" 2>/dev/null) local first_cache=$(echo "$first_request" | grep -i "X-Cache:" | awk '{print $2}' | tr -d '\r') # Second request - should be HIT sleep 0.5 local second_request=$(curl -s -I --max-time 5 "$url" 2>/dev/null) local second_cache=$(echo "$second_request" | grep -i "X-Cache:" | awk '{print $2}' | tr -d '\r') # Check if we got valid responses if [ -z "$first_cache" ] || [ -z "$second_cache" ]; then echo " Status: Skipped (no cache headers)" echo "" continue fi # Display results echo " Request 1: X-Cache: $first_cache" echo " Request 2: X-Cache: $second_cache" # Check if caching worked if [ "$first_cache" = "MISS" ] && [ "$second_cache" = "HIT" ]; then print_success " ✓ CACHING WORKS! (MISS → HIT)" cache_working=1 elif [ "$second_cache" = "HIT" ]; then print_success " ✓ Cache HIT detected" cache_working=1 elif [ "$first_cache" = "MISS" ] && [ "$second_cache" = "MISS" ]; then print_warning " ⚠ No caching (both MISS) - may be dynamic content" else print_info " ℹ Status: $first_cache → $second_cache" fi echo "" done echo "════════════════════════════════════════════════════════════" if [ "$cache_working" -eq 1 ]; then echo "" print_success "✓ PROOF CONFIRMED: Varnish is caching your sites!" echo "" echo "What this means:" echo " • Static files are being cached by Varnish" echo " • Repeat visitors get instant responses from cache" echo " • Server load is reduced for cached content" echo "" else echo "" print_warning "⚠ Could not confirm caching" echo "" echo "Possible reasons:" echo " • Tested URLs are dynamic (admin pages, etc.)" echo " • Cache was already populated (no MISS seen)" echo " • Try option 7 to clear cache, then test again" echo "" fi return 0 } ################################################################################ # DIAGNOSTIC FUNCTIONS ################################################################################ # Run comprehensive diagnostics run_diagnostics() { print_banner "Nginx + Varnish Health Check" local issues_found=0 echo "Checking service status..." echo "" # Check Nginx if systemctl is-active --quiet nginx; then print_success "Nginx is running" else print_error "Nginx is not running" issues_found=$((issues_found + 1)) fi # Check Varnish if systemctl is-active --quiet varnish; then print_success "Varnish is running" # Check if enabled for auto-start on boot if ! systemctl is-enabled --quiet varnish 2>/dev/null; then print_warning "Varnish is NOT enabled (won't start on reboot)" print_info " Run 'Auto-Fix Issues' to enable auto-start" issues_found=$((issues_found + 1)) fi else print_error "Varnish is not running" issues_found=$((issues_found + 1)) fi # Check Apache if systemctl is-active --quiet httpd; then print_success "Apache is running" else print_error "Apache is not running" issues_found=$((issues_found + 1)) fi echo "" echo "Checking port configuration..." echo "" # Check ports using ss (more reliable) or netstat as fallback if command -v ss >/dev/null 2>&1; then # Use ss if available if ss -tlnp 2>/dev/null | grep -E ":80\s.*nginx" >/dev/null; then print_success "Nginx listening on port 80" else print_error "Nginx not listening on port 80" issues_found=$((issues_found + 1)) fi if ss -tlnp 2>/dev/null | grep -E ":443\s.*nginx" >/dev/null; then print_success "Nginx listening on port 443" else print_error "Nginx not listening on port 443" issues_found=$((issues_found + 1)) fi if ss -tlnp 2>/dev/null | grep -E ":${VARNISH_PORT}\s.*varnish" >/dev/null; then print_success "Varnish listening on port $VARNISH_PORT" else print_error "Varnish not listening on port $VARNISH_PORT" issues_found=$((issues_found + 1)) fi if ss -tlnp 2>/dev/null | grep -E ":${APACHE_HTTP_PORT}\s.*httpd" >/dev/null; then print_success "Apache listening on port $APACHE_HTTP_PORT" else print_error "Apache not listening on port $APACHE_HTTP_PORT" issues_found=$((issues_found + 1)) fi else # Fallback to netstat with better patterns if netstat -tlnp 2>/dev/null | awk '$4 ~ /:80$/ && $7 ~ /nginx/' | head -1 | grep -q .; then print_success "Nginx listening on port 80" else print_error "Nginx not listening on port 80" issues_found=$((issues_found + 1)) fi if netstat -tlnp 2>/dev/null | awk '$4 ~ /:443$/ && $7 ~ /nginx/' | head -1 | grep -q .; then print_success "Nginx listening on port 443" else print_error "Nginx not listening on port 443" issues_found=$((issues_found + 1)) fi if netstat -tlnp 2>/dev/null | awk -v port="$VARNISH_PORT" '$4 ~ ":"port"$" && $7 ~ /varnish/' | head -1 | grep -q .; then print_success "Varnish listening on port $VARNISH_PORT" else print_error "Varnish not listening on port $VARNISH_PORT" issues_found=$((issues_found + 1)) fi if netstat -tlnp 2>/dev/null | awk -v port="$APACHE_HTTP_PORT" '$4 ~ ":"port"$" && $7 ~ /httpd/' | head -1 | grep -q .; then print_success "Apache listening on port $APACHE_HTTP_PORT" else print_error "Apache not listening on port $APACHE_HTTP_PORT" issues_found=$((issues_found + 1)) fi fi echo "" echo "Checking configuration files..." echo "" # Check VCL - use varnishadm instead of varnishd -C (more reliable) if [ -f "$VARNISH_VCL" ]; then if varnishadm vcl.list 2>/dev/null | grep -q "active.*warm"; then print_success "Varnish VCL is loaded and active" else print_warning "Varnish VCL may not be active" issues_found=$((issues_found + 1)) fi else print_error "Varnish VCL file not found" issues_found=$((issues_found + 1)) fi # Check Nginx config if nginx -t 2>&1 | grep -q "successful"; then print_success "Nginx configuration is valid" else print_error "Nginx configuration has errors" issues_found=$((issues_found + 1)) fi # Check settings.json configuration if [ -f /etc/nginx/ea-nginx/settings.json ]; then if grep -q "\"apache_port\" : \"${VARNISH_PORT}\"" /etc/nginx/ea-nginx/settings.json; then print_success "settings.json configured for Varnish (port ${VARNISH_PORT})" else print_error "settings.json not configured for Varnish" issues_found=$((issues_found + 1)) fi else print_error "settings.json not found" issues_found=$((issues_found + 1)) fi # Check ea-nginx.conf proxy configuration for HTTP if [ -f /etc/nginx/conf.d/ea-nginx.conf ]; then if grep -q "default ${VARNISH_PORT};" /etc/nginx/conf.d/ea-nginx.conf; then print_success "ea-nginx.conf proxies HTTP to Varnish (port ${VARNISH_PORT})" else print_warning "ea-nginx.conf may not be proxying to Varnish" issues_found=$((issues_found + 1)) fi # Check HTTPS configuration if grep -q "\"apache_ssl_port\" : \"444\"" /etc/nginx/ea-nginx/settings.json 2>/dev/null; then print_success "HTTPS backend configured correctly (Apache:444)" print_info " Note: Config-script forces HTTP protocol for Varnish caching" # Verify config-script has applied HTTP backend override if grep -q 'set $CPANEL_APACHE_PROXY_PASS http://apache_backend_http_' /etc/nginx/conf.d/users/*.conf 2>/dev/null; then print_success " ✓ HTTPS traffic routed through Varnish (HTTP protocol)" else print_warning " ⚠ Config-script override not detected - HTTPS may not cache" print_info " Run 'Auto-Fix Issues' to apply config-script" issues_found=$((issues_found + 1)) fi fi else print_error "ea-nginx.conf not found" issues_found=$((issues_found + 1)) fi echo "" echo "Checking Varnish backend health..." echo "" if command -v varnishadm >/dev/null 2>&1; then if varnishadm backend.list 2>/dev/null | grep -qi "healthy"; then print_success "Varnish backend is healthy" else print_warning "Varnish backend may not be healthy" issues_found=$((issues_found + 1)) fi fi echo "" echo "Checking configuration persistence..." echo "" # Check if config-script safety net exists if [ -f /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish ]; then print_success "Config-script safety net installed" print_info " Auto-fixes if settings.json is overwritten" else print_info "Config-script safety net not installed" print_info " Configuration relies on settings.json RPM preservation" fi echo "" echo "════════════════════════════════════════════════════════════" if [ "$issues_found" -eq 0 ]; then print_success "All checks passed! Configuration is healthy." else print_warning "Found $issues_found issue(s) that may need attention" fi # Always return 0 - finding issues is not a failure, it's information return 0 } # Auto-fix common issues auto_fix_issues() { print_banner "Self-Healing: Auto-Fixing Common Issues" local fixes_applied=0 echo "Checking for common issues and applying fixes..." echo "" # Fix 1: Restart services if not running if ! systemctl is-active --quiet varnish; then echo "Fixing: Varnish is not running..." if systemctl restart varnish; then print_success "Restarted Varnish" fixes_applied=$((fixes_applied + 1)) else print_error "Failed to restart Varnish" fi fi if ! systemctl is-active --quiet nginx; then echo "Fixing: Nginx is not running..." if systemctl restart nginx; then print_success "Restarted Nginx" fixes_applied=$((fixes_applied + 1)) else print_error "Failed to restart Nginx" fi fi # Fix 1b: Enable Varnish for auto-start on boot if ! systemctl is-enabled --quiet varnish 2>/dev/null; then echo "Fixing: Varnish not enabled for auto-start on boot..." if systemctl enable varnish; then print_success "Enabled Varnish (will start on boot)" fixes_applied=$((fixes_applied + 1)) else print_error "Failed to enable Varnish" fi fi # Fix 1c: Verify config-script is applying HTTP backend override for HTTPS if ! grep -q 'set $CPANEL_APACHE_PROXY_PASS http://apache_backend_http_' /etc/nginx/conf.d/users/*.conf 2>/dev/null; then echo "Fixing: HTTPS not configured to use Varnish..." echo " Running config-script to force HTTP backend protocol..." # Run the config-script if bash /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish 2>/dev/null; then print_success "Applied HTTP backend override for HTTPS traffic" print_info " HTTPS now routes through Varnish using HTTP protocol" fixes_applied=$((fixes_applied + 1)) else print_error "Failed to run config-script" fi fi # Fix 2: Check if settings.json has wrong port if [ -f /etc/nginx/ea-nginx/settings.json ]; then if grep -q '"apache_port" : "81"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then echo "Fixing: settings.json has stock port (81) instead of Varnish (6081)..." if modify_settings_json; then print_success "Fixed settings.json (port 6081)" # Rebuild ea-nginx config /usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 systemctl reload nginx fixes_applied=$((fixes_applied + 1)) fi fi fi # Fix 3: Check if ea-nginx.conf has wrong port despite settings.json being correct if [ -f /etc/nginx/conf.d/ea-nginx.conf ]; then if grep -q "default 81;" /etc/nginx/conf.d/ea-nginx.conf 2>/dev/null; then # Check if settings.json is correct first if grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then echo "Fixing: ea-nginx.conf has wrong port, rebuilding from settings.json..." /usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 systemctl reload nginx print_success "Rebuilt ea-nginx.conf from settings.json" fixes_applied=$((fixes_applied + 1)) fi fi fi # Fix 4: Reload systemd if Varnish service override exists but daemon not reloaded if [ -f /etc/systemd/system/varnish.service.d/override.conf ]; then if ! systemctl is-active --quiet varnish; then systemctl daemon-reload print_success "Reloaded systemd configuration" fixes_applied=$((fixes_applied + 1)) fi fi # Fix 5: Rebuild HTTP conf if Nginx config is broken if ! nginx -t >/dev/null 2>&1; then echo "Fixing: Nginx configuration errors..." if /scripts/rebuildhttpdconf; then # After rebuild, ensure settings.json config is applied if grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then /usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 fi systemctl reload nginx print_success "Rebuilt Nginx configuration" fixes_applied=$((fixes_applied + 1)) fi fi # Fix 6: Recreate config-script if missing (safety net) if [ -f "$STATUS_FILE" ] && grep -q "CONFIGURED=yes" "$STATUS_FILE"; then if [ ! -f /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish ]; then echo "Fixing: ea-nginx config-script missing, recreating..." if create_eanginx_config_script; then print_success "Recreated config-script safety net" fixes_applied=$((fixes_applied + 1)) fi fi fi # Fix 7: Restore settings.json.stock backup if settings.json is missing if [ ! -f /etc/nginx/ea-nginx/settings.json ] && [ -f /etc/nginx/ea-nginx/settings.json.stock ]; then echo "Fixing: settings.json missing, restoring from backup..." cp /etc/nginx/ea-nginx/settings.json.stock /etc/nginx/ea-nginx/settings.json # Rebuild ea-nginx config /usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 systemctl reload nginx print_success "Restored settings.json from backup" fixes_applied=$((fixes_applied + 1)) fi echo "" if [ "$fixes_applied" -gt 0 ]; then print_success "Applied $fixes_applied fix(es)" else print_info "No fixes needed" fi return 0 } ################################################################################ # MAIN SETUP FUNCTION ################################################################################ full_setup() { print_banner "Complete Nginx + Varnish Setup" echo "This will install and configure the complete caching stack:" echo "" echo " Stock Apache → ea-nginx (Reverse Proxy) + Varnish (Cache) + Apache" echo "" echo "Components to be installed:" echo " 1. ea-nginx - Nginx reverse proxy (if not already installed)" echo " 2. Varnish Cache - HTTP accelerator" echo " 3. Complete stack configuration" echo "" echo "Traffic flow:" echo " Client → Nginx (80/443) → Varnish (6081) → Apache (81/444)" echo "" print_warning "⚠ IMPORTANT:" print_warning " • This is NOT officially supported by cPanel" print_warning " • Use 'Revert Setup' to completely remove and return to stock Apache" print_warning " • Revert will remove BOTH Nginx and Varnish" echo "" read -p "Continue with complete stack installation? (yes/no): " confirm if [ "$confirm" != "yes" ]; then echo "Installation cancelled." press_enter return 0 fi # Create backup first echo "" print_info "Creating backup of current configuration..." local backup_path=$(create_backup) print_success "Backup created at: $backup_path" # Calculate recommended Varnish memory local total_ram=$(get_total_ram_mb) local recommended_mem=$(calculate_varnish_memory) echo "" echo "Server RAM: ${total_ram}MB" echo "Recommended Varnish memory: ${recommended_mem}MB" echo "" # Step 1: Install cPanel Nginx if not already installed if ! check_nginx_installed; then echo "" print_info "Step 1/5: Installing cPanel Nginx..." if ! install_cpanel_nginx; then print_error "Setup failed at Step 1" press_enter return 0 # Don't crash the script fi else print_success "Step 1/5: cPanel Nginx already installed" fi # Step 2: Install Varnish if ! check_varnish_installed; then echo "" print_info "Step 2/5: Installing Varnish..." if ! install_varnish; then print_error "Setup failed at Step 2" press_enter return 0 # Don't crash the script fi else print_success "Step 2/5: Varnish already installed" fi # Step 3: Configure Varnish echo "" print_info "Step 3/5: Configuring Varnish..." if ! configure_varnish_vcl; then print_error "Setup failed at Step 3" press_enter return 1 fi if ! configure_varnish_port "$recommended_mem"; then print_error "Setup failed at Step 3" press_enter return 1 fi # Step 4: Modify settings.json and configure Nginx to proxy to Varnish # Apache stays on stock ea-nginx ports (81/444) - NO changes needed! echo "" print_info "Step 4/5: Configuring Nginx to proxy to Varnish..." # First, modify settings.json to use Varnish port if ! modify_settings_json; then print_error "Setup failed at Step 4 (settings.json modification)" press_enter return 1 fi # Then rebuild ea-nginx config from modified settings.json if ! configure_nginx_varnish_proxy; then print_error "Setup failed at Step 4 (nginx configuration)" press_enter return 1 fi # Step 5: Start services echo "" print_info "Step 5/5: Starting services..." systemctl enable varnish systemctl restart varnish if systemctl is-active --quiet varnish; then print_success "Varnish started successfully" if systemctl is-enabled --quiet varnish; then print_success "Varnish enabled (auto-start on boot)" fi else print_error "Failed to start Varnish" press_enter return 1 fi systemctl restart nginx if systemctl is-active --quiet nginx; then print_success "Nginx restarted successfully" else print_error "Failed to restart Nginx" press_enter return 1 fi # Create ea-nginx config-script as safety net echo "" print_info "Installing config-script for HTTPS→Varnish routing..." create_eanginx_config_script # Run config-script immediately to enable HTTPS caching print_info "Applying HTTPS caching configuration..." if bash /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish 2>/dev/null; then print_success "HTTPS traffic now routes through Varnish (HTTP protocol)" else print_warning "Config-script execution had issues - check logs" fi # Mark as configured cat > "$STATUS_FILE" </dev/null; then has_varnish_config=true fi fi # Check if ea-nginx is installed if check_nginx_installed; then has_nginx=true fi # Check if Varnish is installed if check_varnish_installed; then has_varnish=true fi # If nothing to revert, exit if [ "$has_nginx" = "false" ] && [ "$has_varnish" = "false" ] && [ "$has_varnish_config" = "false" ]; then print_warning "Nothing to revert:" print_info " • ea-nginx not installed" print_info " • Varnish not installed" print_info " • No Varnish configuration found" echo "" print_success "System is already in stock Apache-only configuration" press_enter return 0 fi # Show what's currently installed echo "Current state:" if [ "$has_nginx" = "true" ]; then echo " ✓ ea-nginx installed" else echo " ✗ ea-nginx not installed" fi if [ "$has_varnish" = "true" ]; then echo " ✓ Varnish installed" else echo " ✗ Varnish not installed" fi if [ "$has_varnish_config" = "true" ]; then echo " ✓ Varnish configuration active" else echo " ✗ Varnish configuration not active" fi echo "" # Show appropriate revert options based on what's installed echo "Available revert options:" echo "" local option_count=0 local partial_option="" local full_option="" # Option 1: Partial revert (only if Varnish exists) if [ "$has_varnish" = "true" ] || [ "$has_varnish_config" = "true" ]; then option_count=$((option_count + 1)) partial_option="1" echo " 1) Partial Revert - Remove Varnish only (keep Nginx + Apache)" echo " • Removes Varnish caching layer" echo " • Keeps ea-nginx reverse proxy" echo " • Result: Client → Nginx → Apache" echo "" fi # Option 2: Full revert (if Nginx exists OR Varnish stuff needs cleanup) if [ "$has_nginx" = "true" ] || [ "$has_varnish" = "true" ] || [ "$has_varnish_config" = "true" ]; then option_count=$((option_count + 1)) if [ -z "$partial_option" ]; then full_option="1" echo " 1) Full Revert - Remove everything (return to stock Apache)" else full_option="2" echo " 2) Full Revert - Remove everything (return to stock Apache)" fi if [ "$has_varnish" = "true" ]; then echo " • Removes Varnish caching layer" fi if [ "$has_nginx" = "true" ]; then echo " • Removes ea-nginx reverse proxy" fi if [ "$has_varnish_config" = "true" ]; then echo " • Cleans up Varnish configuration" fi echo " • Result: Client → Apache (stock cPanel)" echo "" fi echo " 0) Cancel" echo "" read -p "Select option: " revert_choice case $revert_choice in "$partial_option") if [ -n "$partial_option" ]; then revert_partial else print_error "Invalid option" press_enter return 1 fi ;; "$full_option") if [ -n "$full_option" ]; then revert_full else print_error "Invalid option" press_enter return 1 fi ;; 0) echo "Revert cancelled." press_enter return 0 ;; *) print_error "Invalid option" press_enter return 1 ;; esac } revert_partial() { print_banner "Partial Revert - Remove Varnish Only" echo "This will:" echo " 1. Stop and remove Varnish" echo " 2. Configure Nginx to proxy directly to Apache" echo " 3. Keep ea-nginx (Nginx reverse proxy)" echo "" print_info "Result: Client → Nginx → Apache (no caching)" echo "" read -p "Continue with partial revert? (yes/no): " confirm if [ "$confirm" != "yes" ]; then echo "Partial revert cancelled." press_enter return 0 fi # Create backup before reverting echo "" print_info "Creating backup before revert..." local backup_path=$(create_backup) print_success "Backup created at: $backup_path" # Stop Varnish echo "" print_info "Stopping Varnish..." systemctl stop varnish || true systemctl disable varnish || true # Restore settings.json to stock echo "" restore_settings_json # Rebuild ea-nginx config from restored settings.json print_info "Rebuilding ea-nginx configuration..." /usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 || true print_success "Nginx now proxies directly to Apache (port 81)" # Reload Nginx print_info "Reloading Nginx..." systemctl reload nginx # Remove ea-nginx config script (safety net no longer needed) echo "" remove_eanginx_config_script # Remove status file rm -f "$STATUS_FILE" echo "" print_success "Varnish configuration reverted" echo "" # Remove Varnish package print_info "Removing Varnish package..." yum remove -y varnish >/dev/null 2>&1 || true print_success "Varnish package removed" echo "" print_success "═══════════════════════════════════════════════════════" print_success "Partial revert completed" print_success "═══════════════════════════════════════════════════════" echo "" print_info "Your server configuration:" print_info " • Nginx reverse proxy still active (ea-nginx)" print_info " • Client → Nginx (80/443) → Apache (81/444)" print_info " • No Varnish caching layer" echo "" print_info "Benefits you still have:" print_info " • Nginx connection handling and buffering" print_info " • Support for modern protocols (HTTP/2, etc.)" echo "" print_info "To fully remove Nginx and return to stock Apache:" print_info " Run this revert option again and choose 'Full Revert'" press_enter } revert_full() { print_banner "Full Revert - Return to Stock Apache" # Check what needs to be removed local has_varnish=$(check_varnish_installed && echo "true" || echo "false") local has_nginx=$(check_nginx_installed && echo "true" || echo "false") local has_config=$([ -f /etc/nginx/ea-nginx/settings.json ] && grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null && echo "true" || echo "false") echo "This will remove:" [ "$has_varnish" = "true" ] && echo " • Varnish package" [ "$has_nginx" = "true" ] && echo " • ea-nginx package" [ "$has_config" = "true" ] && echo " • Varnish configuration" [ "$has_varnish" = "false" ] && [ "$has_nginx" = "false" ] && [ "$has_config" = "false" ] && echo " • Clean up any remaining configuration" echo "" echo "Result: Stock cPanel Apache-only configuration" echo "" print_warning "⚠ WARNING: This returns your server to stock Apache-only" echo "" read -p "Continue with full revert? (yes/no): " confirm if [ "$confirm" != "yes" ]; then echo "Full revert cancelled." press_enter return 0 fi # Create backup before reverting (if there's anything to backup) if [ "$has_config" = "true" ]; then echo "" print_info "Creating backup before revert..." local backup_path=$(create_backup) print_success "Backup created at: $backup_path" fi # Stop Varnish (if running) (if running) if systemctl is-active --quiet varnish 2>/dev/null; then echo "" print_info "Stopping Varnish..." systemctl stop varnish || true systemctl disable varnish || true fi # Restore settings.json to stock (if configured) if [ -f /etc/nginx/ea-nginx/settings.json ]; then if grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then echo "" restore_settings_json # Rebuild ea-nginx config from restored settings.json print_info "Rebuilding ea-nginx configuration..." /usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 || true print_success "Configuration restored" # Reload Nginx before removing it if systemctl is-active --quiet nginx 2>/dev/null; then print_info "Reloading Nginx..." systemctl reload nginx fi fi fi # Remove ea-nginx config script (if exists) if [ -f /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish ]; then echo "" remove_eanginx_config_script fi # Remove status file (if exists) if [ -f "$STATUS_FILE" ]; then rm -f "$STATUS_FILE" fi echo "" print_success "Varnish configuration cleaned up" echo "" # Remove Varnish package (if installed) if check_varnish_installed; then print_info "Removing Varnish package..." yum remove -y varnish >/dev/null 2>&1 || true print_success "Varnish package removed" else print_info "Varnish package already removed" fi # Remove ea-nginx and return to stock Apache if check_nginx_installed; then echo "" print_info "Removing ea-nginx (Nginx reverse proxy)..." print_warning " This will return your server to stock Apache-only configuration" if /usr/local/cpanel/scripts/ea-nginx disable >/dev/null 2>&1; then print_success "ea-nginx disabled" fi if yum remove -y ea-nginx >/dev/null 2>&1; then print_success "ea-nginx package removed" fi else echo "" print_info "ea-nginx already removed" fi # Restart Apache to ensure it's listening on port 80/443 echo "" print_info "Restarting Apache on stock ports..." systemctl restart httpd if systemctl is-active --quiet httpd; then print_success "Apache is now running on ports 80/443 (stock configuration)" fi echo "" print_success "═══════════════════════════════════════════════════════" print_success "Full revert completed" print_success "═══════════════════════════════════════════════════════" echo "" print_info "Your server has been returned to:" print_info " • Stock cPanel Apache-only configuration" print_info " • Apache listening directly on ports 80/443" print_info " • No Nginx reverse proxy" print_info " • No Varnish caching" press_enter } ################################################################################ # MEMORY ADJUSTMENT FUNCTIONS ################################################################################ adjust_varnish_memory() { print_banner "Adjust Varnish Memory Allocation" if ! check_varnish_installed; then print_error "Varnish is not installed" press_enter return 0 # Don't crash the script fi local total_ram=$(get_total_ram_mb) local current_mem=$(grep "ExecStart.*malloc" /etc/systemd/system/varnish.service.d/override.conf 2>/dev/null | grep -oP 'malloc,\K[0-9]+' || echo "unknown") echo "Server total RAM: ${total_ram}MB" echo "Current Varnish memory: ${current_mem}MB" echo "" echo "Select memory allocation:" echo "" echo " 1) 256MB - For servers with <2GB RAM" echo " 2) 512MB - For servers with 2-4GB RAM" echo " 3) 1GB - For servers with 4-8GB RAM" echo " 4) 2GB - For servers with 8-16GB RAM" echo " 5) 4GB - For servers with 16GB+ RAM" echo " 6) Custom amount" echo " 7) Auto-calculate based on current RAM usage" echo " 0) Cancel" echo "" read -p "Select option: " mem_choice local new_mem="" case $mem_choice in 1) new_mem=256 ;; 2) new_mem=512 ;; 3) new_mem=1024 ;; 4) new_mem=2048 ;; 5) new_mem=4096 ;; 6) echo "" read -p "Enter custom memory in MB (or 0 to cancel): " custom_mem if [ "$custom_mem" = "0" ] || [ -z "$custom_mem" ]; then echo "Cancelled." press_enter return 0 fi new_mem="$custom_mem" ;; 7) new_mem=$(calculate_varnish_memory) echo "" print_info "Auto-calculated memory: ${new_mem}MB" ;; 0) echo "Cancelled." press_enter return 0 ;; *) print_error "Invalid option" press_enter return 1 ;; esac if [ -z "$new_mem" ]; then print_error "Invalid memory value" press_enter return 1 fi echo "" print_info "Setting Varnish memory to ${new_mem}MB..." configure_varnish_port "$new_mem" echo "" print_info "Restarting Varnish..." if systemctl restart varnish; then print_success "Varnish memory updated to ${new_mem}MB" # Update status file if [ -f "$STATUS_FILE" ]; then sed -i "s/VARNISH_MEMORY=.*/VARNISH_MEMORY=${new_mem}m/" "$STATUS_FILE" fi else print_error "Failed to restart Varnish" fi press_enter } ################################################################################ # CACHE MANAGEMENT FUNCTIONS ################################################################################ manage_varnish_cache() { print_banner "Varnish Cache Management" if ! systemctl is-active --quiet varnish; then print_error "Varnish is not running" press_enter return 0 # Don't crash the script fi echo " 1) Clear all cache" echo " 2) Clear cache for specific domain" echo " 3) View cache statistics" echo " 4) View cache hit ratio" echo " 0) Cancel" echo "" read -p "Select option: " cache_choice case $cache_choice in 1) echo "" print_info "Clearing all Varnish cache..." if varnishadm "ban req.url ~ /" 2>/dev/null; then print_success "Cache cleared successfully" else print_error "Failed to clear cache" fi ;; 2) echo "" read -p "Enter domain name (or 0 to cancel): " domain if [ "$domain" = "0" ] || [ -z "$domain" ]; then echo "Cancelled." else print_info "Clearing cache for $domain..." if varnishadm "ban req.http.host == $domain" 2>/dev/null; then print_success "Cache cleared for $domain" else print_error "Failed to clear cache" fi fi ;; 3) echo "" print_info "Varnish cache statistics (press 'q' to quit):" echo "" varnishstat || print_error "Failed to get statistics" ;; 4) echo "" print_info "Cache hit ratio:" echo "" varnishstat -1 | grep -E 'cache_hit|cache_miss' || print_error "Failed to get statistics" ;; 0) return 0 ;; *) print_error "Invalid option" ;; esac press_enter } ################################################################################ # BACKUP/RESTORE FUNCTIONS ################################################################################ manage_backups() { print_banner "Backup & Restore Management" echo " 1) Create new backup" echo " 2) List available backups" echo " 3) Restore from backup" echo " 0) Cancel" echo "" read -p "Select option: " backup_choice case $backup_choice in 1) echo "" print_info "Creating backup..." local backup_path=$(create_backup) print_success "Backup created at: $backup_path" ;; 2) echo "" if [ -d "$BACKUP_DIR" ] && [ "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then echo "Available backups:" echo "" ls -lh "$BACKUP_DIR" | grep "^d" | awk '{print $9, "("$6, $7, $8")"}' else print_info "No backups found" fi ;; 3) echo "" if [ ! -d "$BACKUP_DIR" ] || [ ! "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then print_error "No backups available" press_enter return 0 # Don't crash the script fi echo "Available backups:" echo "" local backups=($(ls -d "$BACKUP_DIR"/backup_* 2>/dev/null | sort -r)) local count=1 for backup in "${backups[@]}"; do echo " $count) $(basename "$backup")" count=$((count + 1)) done echo " 0) Cancel" echo "" read -p "Select backup to restore: " restore_choice if [ "$restore_choice" = "0" ]; then echo "Cancelled." elif [ "$restore_choice" -ge 1 ] && [ "$restore_choice" -lt "$count" ]; then local selected_backup="${backups[$((restore_choice - 1))]}" echo "" print_warning "This will restore configuration from: $(basename "$selected_backup")" read -p "Continue? (yes/no): " confirm if [ "$confirm" = "yes" ]; then print_info "Restoring backup..." # Check disk space before restore local available_space=$(df /etc | tail -1 | awk '{print $4}') if [ "$available_space" -lt 10240 ]; then print_error "Insufficient disk space (less than 10MB available)" press_enter return 0 # Don't crash the script fi # Restore files [ -f "$selected_backup/ea-nginx.conf" ] && cp -f "$selected_backup/ea-nginx.conf" /etc/nginx/ [ -d "$selected_backup/conf.d" ] && cp -rf "$selected_backup/conf.d/"* /etc/nginx/conf.d/ [ -f "$selected_backup/default.vcl" ] && cp -f "$selected_backup/default.vcl" /etc/varnish/ # Reload services systemctl daemon-reload systemctl reload nginx || true systemctl restart varnish || true print_success "Backup restored successfully" else echo "Restore cancelled." fi else print_error "Invalid selection" fi ;; 0) return 0 ;; *) print_error "Invalid option" ;; esac press_enter } ################################################################################ # VIEW LOGS FUNCTION ################################################################################ view_logs() { print_banner "View Service Logs" echo " 1) Varnish logs (live)" echo " 2) Nginx error log (tail)" echo " 3) Nginx access log (tail)" echo " 4) Apache error log (tail)" echo " 0) Cancel" echo "" read -p "Select option: " log_choice case $log_choice in 1) echo "" print_info "Viewing Varnish logs (press Ctrl+C to exit)..." echo "" varnishlog || print_error "Failed to view logs" ;; 2) echo "" print_info "Viewing Nginx error log (press Ctrl+C to exit)..." echo "" tail -f /var/log/nginx/error.log || print_error "Failed to view logs" ;; 3) echo "" print_info "Viewing Nginx access log (press Ctrl+C to exit)..." echo "" tail -f /var/log/nginx/access.log || print_error "Failed to view logs" ;; 4) echo "" print_info "Viewing Apache error log (press Ctrl+C to exit)..." echo "" tail -f /usr/local/apache/logs/error_log || print_error "Failed to view logs" ;; 0) return 0 ;; *) print_error "Invalid option" ;; esac press_enter } ################################################################################ # MAIN MENU ################################################################################ show_varnish_menu() { clear print_banner "Nginx + Varnish Caching Manager" # Detect current mode local has_nginx=$(check_nginx_installed && echo "true" || echo "false") local has_varnish=$(check_varnish_installed && echo "true" || echo "false") local has_varnish_config=$([ -f /etc/nginx/ea-nginx/settings.json ] && grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null && echo "true" || echo "false") # Determine mode local mode="" local mode_color="" if [ "$has_varnish" = "true" ] && [ "$has_nginx" = "true" ] && [ "$has_varnish_config" = "true" ]; then mode="Varnish + Nginx + Apache (Full Stack)" mode_color="${GREEN}" elif [ "$has_nginx" = "true" ]; then mode="Nginx + Apache (Reverse Proxy)" mode_color="${YELLOW}" else mode="Apache Only (Stock cPanel)" mode_color="${YELLOW}" fi echo -e "${mode_color}● Mode: ${mode}${NC}" # Show installation info if configured if [ "$has_varnish_config" = "true" ] && [ -f "$STATUS_FILE" ]; then local install_date=$(grep "INSTALL_DATE" "$STATUS_FILE" | cut -d= -f2) local varnish_mem=$(grep "VARNISH_MEMORY" "$STATUS_FILE" | cut -d= -f2) echo " Installed: $install_date" echo " Varnish Memory: $varnish_mem" fi # Always show port status with color coding echo "" echo " Services & Ports:" # Check Nginx ports (80/443) if ss -tlnp 2>/dev/null | grep -E ":80\s.*nginx" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:80$/ && $7 ~ /nginx/' | grep -q .; then echo -e " ${GREEN}✓${NC} Nginx: 80" elif ss -tlnp 2>/dev/null | grep -E ":80\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:80$/ && $7 ~ /httpd/' | grep -q .; then echo -e " ${GREEN}✓${NC} Apache: 80 (direct)" else echo -e " ${RED}✗${NC} Port 80 (not active)" fi if ss -tlnp 2>/dev/null | grep -E ":443\s.*nginx" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:443$/ && $7 ~ /nginx/' | grep -q .; then echo -e " ${GREEN}✓${NC} Nginx: 443" elif ss -tlnp 2>/dev/null | grep -E ":443\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:443$/ && $7 ~ /httpd/' | grep -q .; then echo -e " ${GREEN}✓${NC} Apache: 443 (direct)" else echo -e " ${RED}✗${NC} Port 443 (not active)" fi # Check Varnish port (6081) if ss -tlnp 2>/dev/null | grep -E ":${VARNISH_PORT}\s.*varnish" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk -v port="$VARNISH_PORT" '$4 ~ ":"port"$" && $7 ~ /varnish/' | grep -q .; then echo -e " ${GREEN}✓${NC} Varnish: ${VARNISH_PORT}" else echo -e " ${RED}✗${NC} Varnish: ${VARNISH_PORT}" fi # Check Apache backend ports (81/444) if ss -tlnp 2>/dev/null | grep -E ":${APACHE_HTTP_PORT}\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk -v port="$APACHE_HTTP_PORT" '$4 ~ ":"port"$" && $7 ~ /httpd/' | grep -q .; then echo -e " ${GREEN}✓${NC} Apache: ${APACHE_HTTP_PORT}" else echo -e " ${RED}✗${NC} Apache: ${APACHE_HTTP_PORT}" fi if ss -tlnp 2>/dev/null | grep -E ":${APACHE_HTTPS_PORT}\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk -v port="$APACHE_HTTPS_PORT" '$4 ~ ":"port"$" && $7 ~ /httpd/' | grep -q .; then echo -e " ${GREEN}✓${NC} Apache: ${APACHE_HTTPS_PORT}" else echo -e " ${RED}✗${NC} Apache: ${APACHE_HTTPS_PORT}" fi echo "" echo -e "${BOLD}Setup & Installation:${NC}" echo "" echo " 1) Full Setup - Install and configure complete stack" echo " 2) Revert Setup - Remove Varnish integration" echo "" echo -e "${BOLD}Diagnostics & Maintenance:${NC}" echo "" echo " 3) Run Health Check - Diagnose configuration issues" echo " 4) Auto-Fix Issues - Self-healing diagnostics" echo " 5) Proof of Caching - Quick test showing MISS → HIT pattern" echo "" echo -e "${BOLD}Optimization:${NC}" echo "" echo " 6) Adjust Varnish Memory - Change RAM allocation" echo " 7) Manage Varnish Cache - Clear cache, view stats" echo "" echo -e "${BOLD}Advanced:${NC}" echo "" echo " 8) Backup & Restore - Manage configuration backups" echo " 9) View Logs - Service logs and monitoring" echo "" echo " 0) Return to Performance Menu" echo "" echo "═══════════════════════════════════════════════════════════" echo -n "Select option: " } # Main loop run_varnish_manager() { while true; do show_varnish_menu read -r choice case $choice in 1) full_setup ;; 2) revert_setup ;; 3) run_diagnostics; press_enter ;; 4) auto_fix_issues; press_enter ;; 5) proof_of_caching; press_enter ;; 6) adjust_varnish_memory ;; 7) manage_varnish_cache ;; 8) manage_backups ;; 9) view_logs ;; 0) clear exit 0 ;; *) echo "" print_error "Invalid option" sleep 1 ;; esac done } # Run main menu run_varnish_manager