212af57746
Apache VirtualHosts listen on the public IP, not localhost. Script now detects primary server IP and configures Varnish backend accordingly.
2166 lines
75 KiB
Bash
Executable File
2166 lines
75 KiB
Bash
Executable File
#!/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" <<EOFSETTINGS
|
||
{
|
||
"apache_port" : "6081",
|
||
"apache_port_ip" : "127.0.0.1",
|
||
"apache_ssl_port" : "444",
|
||
"apache_ssl_port_ip" : "127.0.0.1",
|
||
"client_max_body_size" : "128m"
|
||
}
|
||
EOFSETTINGS
|
||
|
||
if grep -q '"apache_port" : "6081"' "$settings_file"; then
|
||
print_success "settings.json updated successfully"
|
||
echo ""
|
||
print_info "Configuration Applied:"
|
||
print_info " • HTTP traffic (port 80) → Varnish:6081 → Apache:81 [CACHED]"
|
||
print_info " • HTTPS traffic (port 443) → Varnish:6081 → Apache:81 [CACHED]"
|
||
echo ""
|
||
print_success "Both HTTP and HTTPS will be cached by Varnish"
|
||
print_info " Method: SSL termination at Nginx, HTTP backends to Varnish"
|
||
print_info " Safety: Config-script maintains configuration after ea-nginx rebuilds"
|
||
return 0
|
||
else
|
||
print_error "Failed to update settings.json"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Restore ea-nginx settings.json to stock
|
||
restore_settings_json() {
|
||
local settings_file="/etc/nginx/ea-nginx/settings.json"
|
||
|
||
print_info "Restoring ea-nginx settings.json to stock configuration..."
|
||
|
||
if [ -f "${settings_file}.stock" ]; then
|
||
cp "${settings_file}.stock" "$settings_file"
|
||
rm -f "${settings_file}.stock"
|
||
print_success "settings.json restored to stock (port 81)"
|
||
else
|
||
# Create stock settings if backup doesn't exist
|
||
cat > "$settings_file" <<EOFSETTINGS
|
||
{
|
||
"apache_port" : "81",
|
||
"apache_port_ip" : "127.0.0.1",
|
||
"apache_ssl_port" : "444",
|
||
"apache_ssl_port_ip" : "127.0.0.1",
|
||
"client_max_body_size" : "128m"
|
||
}
|
||
EOFSETTINGS
|
||
print_success "settings.json reset to stock defaults"
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# Create ea-nginx config script for automatic recovery
|
||
create_eanginx_config_script() {
|
||
local config_script="/etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish"
|
||
|
||
print_info "Creating ea-nginx config script for automatic recovery..."
|
||
|
||
# Ensure directory exists
|
||
mkdir -p /etc/nginx/ea-nginx/config-scripts/global
|
||
|
||
# Create the config script
|
||
cat > "$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
|
||
|
||
# ============================================================================
|
||
# Force HTTPS traffic to use HTTP backend protocol (enables HTTPS caching)
|
||
# ============================================================================
|
||
# This processes all per-domain configs to force HTTP backend for both
|
||
# HTTP and HTTPS traffic. Without this, HTTPS bypasses Varnish.
|
||
#
|
||
# Original: $scheme://apache_backend_${scheme}_IP (HTTP->HTTP, HTTPS->HTTPS)
|
||
# Modified: http://apache_backend_http_IP (both use HTTP backend)
|
||
# ============================================================================
|
||
|
||
log_message "Processing per-domain configs to force HTTP backend for HTTPS..."
|
||
|
||
domain_count=0
|
||
modified_count=0
|
||
|
||
# Process all per-domain config files
|
||
for config_file in /etc/nginx/conf.d/users/*.conf; do
|
||
[ -f "$config_file" ] || continue
|
||
domain_count=$((domain_count + 1))
|
||
|
||
# Check if this domain needs fixing (uses scheme-based backend)
|
||
if grep -q '\$scheme://apache_backend_\${scheme}_' "$config_file" 2>/dev/null; then
|
||
# Force HTTP backend protocol for all traffic (enables HTTPS caching)
|
||
if sed -i 's|\$scheme://apache_backend_\${\?scheme\?}_|http://apache_backend_http_|g' "$config_file" 2>/dev/null; then
|
||
modified_count=$((modified_count + 1))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
if [ $modified_count -gt 0 ]; then
|
||
log_message "SUCCESS: Modified $modified_count of $domain_count domain configs to use HTTP backend"
|
||
log_message "HTTPS traffic now routes through Varnish (SSL terminates at Nginx, HTTP to backend)"
|
||
else
|
||
log_message "All $domain_count domain configs already use HTTP backend. No changes 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"
|
||
|
||
# Get server's primary IP address for Apache backend
|
||
local server_ip=$(hostname -I | awk '{print $1}')
|
||
if [ -z "$server_ip" ]; then
|
||
server_ip="127.0.0.1"
|
||
print_warning "Could not detect server IP, using 127.0.0.1"
|
||
else
|
||
print_info "Detected server IP: $server_ip"
|
||
fi
|
||
|
||
# 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 = "SERVER_IP_PLACEHOLDER";
|
||
.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
|
||
|
||
# Replace placeholder with actual server IP
|
||
sed -i "s/SERVER_IP_PLACEHOLDER/$server_ip/g" "$VARNISH_VCL"
|
||
|
||
# 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 <<EOFSERVICE
|
||
[Service]
|
||
ExecStart=
|
||
ExecStart=/usr/sbin/varnishd -a :${VARNISH_PORT} -f /etc/varnish/default.vcl -s malloc,${varnish_mem}m
|
||
EOFSERVICE
|
||
|
||
systemctl daemon-reload
|
||
|
||
print_success "Varnish configured to use port $VARNISH_PORT with ${varnish_mem}m RAM"
|
||
|
||
return 0
|
||
}
|
||
|
||
# Configure Nginx to proxy to Varnish
|
||
configure_nginx_varnish_proxy() {
|
||
print_banner "Configuring Nginx to Proxy to Varnish"
|
||
|
||
# With settings.json approach, we just rebuild ea-nginx config
|
||
# ea-nginx reads settings.json (with apache_port = 6081) and generates correct config
|
||
echo "Rebuilding ea-nginx configuration from settings.json..."
|
||
if /usr/local/cpanel/scripts/ea-nginx config --global >/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" <<EOFSTATUS
|
||
CONFIGURED=yes
|
||
INSTALL_DATE=$(date +%Y-%m-%d)
|
||
VARNISH_MEMORY=${recommended_mem}m
|
||
BACKUP_PATH=$backup_path
|
||
EOFSTATUS
|
||
|
||
echo ""
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
print_success "Setup completed successfully!"
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
|
||
# Run diagnostics
|
||
echo ""
|
||
run_diagnostics
|
||
|
||
# Test domains
|
||
echo ""
|
||
print_info "Testing domain accessibility..."
|
||
echo ""
|
||
|
||
local test_domains=$(get_cpanel_domains | head -5)
|
||
if [ -n "$test_domains" ]; then
|
||
while IFS= read -r domain; do
|
||
test_domain "$domain" "http" || true
|
||
test_domain "$domain" "https" || true
|
||
done <<< "$test_domains"
|
||
else
|
||
print_warning "No domains found to test"
|
||
fi
|
||
|
||
echo ""
|
||
print_info "═══════════════════════════════════════════════════════"
|
||
print_info "Configuration Persistence:"
|
||
echo ""
|
||
print_success "✓ settings.json modified (apache_port = 6081)"
|
||
print_info " ea-nginx natively generates correct proxy config"
|
||
print_info " Preserved by RPM during package updates"
|
||
echo ""
|
||
print_success "✓ ea-nginx config-script installed (safety net)"
|
||
print_info " Auto-fixes if settings.json ever falls back to defaults"
|
||
print_info " Logs to: /var/log/nginx-varnish-hook.log"
|
||
echo ""
|
||
print_info "Backup: /etc/nginx/ea-nginx/settings.json.stock"
|
||
print_info "Backup location: $backup_path"
|
||
echo ""
|
||
print_warning "⚠ IMPORTANT NOTES:"
|
||
print_warning " • This setup is NOT officially supported by cPanel"
|
||
print_warning " • Config-script maintains configuration after ea-nginx updates"
|
||
print_success " ✓ Both HTTP and HTTPS traffic are cached by Varnish"
|
||
echo ""
|
||
print_info "To completely remove:"
|
||
print_info " • Use 'Revert Setup' to remove Nginx + Varnish"
|
||
print_info " • Returns server to stock Apache-only configuration"
|
||
echo ""
|
||
print_info "How HTTPS caching works:"
|
||
print_info " • SSL terminates at Nginx (standard practice)"
|
||
print_info " • Backend uses HTTP protocol to Varnish (config-script override)"
|
||
print_info " • Varnish caches all static content for both protocols"
|
||
echo ""
|
||
print_info "If using Cloudflare: This provides origin-level caching behind CDN"
|
||
print_info "═══════════════════════════════════════════════════════"
|
||
|
||
press_enter
|
||
}
|
||
|
||
################################################################################
|
||
# REVERT FUNCTION
|
||
################################################################################
|
||
|
||
revert_setup() {
|
||
print_banner "Revert Nginx + Varnish Setup"
|
||
|
||
# Check what's actually installed
|
||
local has_varnish_config=false
|
||
local has_nginx=false
|
||
local has_varnish=false
|
||
|
||
# Check Varnish configuration
|
||
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
|
||
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
|