diff --git a/modules/website/wordpress/wordpress-cron-manager.sh b/modules/website/wordpress/wordpress-cron-manager.sh index aa620b7..7c00bd5 100755 --- a/modules/website/wordpress/wordpress-cron-manager.sh +++ b/modules/website/wordpress/wordpress-cron-manager.sh @@ -1418,14 +1418,25 @@ create_timestamped_backup() { # Function to generate staggered cron time # Distributes jobs across 60 minutes to avoid load spikes generate_staggered_cron() { + # CRITICAL: Stagger cron times to prevent all WordPress sites from running at once + # This prevents server load spikes from concurrent execution + # Each site gets a different minute within the hour, spread across 60 minutes + + # Calculate staggered minute (0-59) - each site gets a different minute local minute=$((CRON_OFFSET % 60)) - # Create pattern: every hour at staggered minutes - # Site 1: minute 0, Site 2: minute 1, etc. - # Increment offset for next site (wraps at 60) + # For better distribution, use every 3 minutes instead of every minute + # This gives us 20 different time slots instead of 60 + # Site 1: min 0, Site 2: min 3, Site 3: min 6, etc. + local stagger_minute=$((minute * 3)) + stagger_minute=$((stagger_minute % 60)) + + # Increment offset for next site CRON_OFFSET=$((CRON_OFFSET + 1)) - echo "$minute * * * *" + # Return cron schedule: run every hour at the staggered minute + # This ensures each WordPress site runs at a different time to prevent load spikes + echo "$stagger_minute * * * *" } # Function to extract user from WordPress site path @@ -1438,18 +1449,33 @@ extract_user_from_path() { cpanel) # Extract user from /home/username/public_html pattern user=$(echo "$site_path" | awk -F'/' '{print $3}') + # Validate extraction - if empty, try alternative extraction + if [ -z "$user" ]; then + user=$(stat -c %U "$site_path" 2>/dev/null) + fi ;; interworx) # Extract user from /home/username/domain/html pattern user=$(echo "$site_path" | awk -F'/' '{print $3}') + # Validate extraction - if empty, try alternative extraction + if [ -z "$user" ]; then + user=$(stat -c %U "$site_path" 2>/dev/null) + fi ;; plesk) # Extract domain from path and lookup user local domain=$(echo "$site_path" | grep -oE '/vhosts/[^/]+' | sed 's|/vhosts/||') user=$(plesk bin subscription --info "$domain" 2>/dev/null | grep "Owner" | awk '{print $2}') + # Fallback to file owner if plesk lookup fails + if [ -z "$user" ]; then + user=$(stat -c %U "$site_path" 2>/dev/null) + fi ;; *) - user="www-data" + # Default to file owner if panel detection fails + user=$(stat -c %U "$site_path" 2>/dev/null) + if [ -z "$user" ]; then + user="www-data" ;; esac