As a hosting provider, one of the most common requests you’ll receive is WordPress installation. While manual installations work fine for occasional setups, they become time-consuming and error-prone when dealing with multiple clients or specific hosting plans designed for WordPress users. This is where cPanel hooks come to the rescue. The following script will use cPanel hooks to automatically install cPanel on an account that has a designated plan for WordPress setup.
- Plan Verification: Only installs WordPress for accounts created on the designated plan (e.g., “wordpress-plan”).
- Database Creation: Automatically creates a MySQL database and user with secure credentials.
- WordPress Download: Fetches the latest WordPress version and extracts it to the account’s public_html directory.
- Configuration: Sets up wp-config.php with database credentials and security keys.
- Installation Completion: Uses WP-CLI to complete the WordPress installation process.
- Credential Management: Saves login credentials securely for the account owner._
Step 1: Create the Hook Script
Place the hook script in /usr/local/cpanel/scripts/
and name it something descriptive like post_wwwacct_wordpress_installer
. The script must be executable and follow cPanel’s hook conventions.
Step 2: Configure Plan-Specific Installation
The script checks the hosting plan name before proceeding with installation. This ensures WordPress is only installed for accounts on designated plans:
Step 3: Register the Hook
After creating the script, register it with cPanel’s hook system:
/usr/local/cpanel/bin/manage_hooks add script \
/usr/local/cpanel/scripts/post_wwwacct_wordpress_installer \
--category=Whostmgr --event=Accounts::Create --stage=post
WORDPRESS_PLAN=“wordpress-plan” # Customize this value
Here’s the hook script:
#!/bin/bash # cPanel post_wwwacct Hook for Automatic WordPress Installation # File: /usr/local/cpanel/scripts/post_wwwacct_wordpress_installer # # This script automatically installs WordPress when a new account is created # on a specific hosting plan (e.g., "wordpress-plan") # # Installation: # 1. Place this file in /usr/local/cpanel/scripts/ # 2. Make it executable: chmod +x /usr/local/cpanel/scripts/post_wwwacct_wordpress_installer # 3. Register the hook: /usr/local/cpanel/bin/manage_hooks add script /usr/local/cpanel/scripts/post_wwwacct_wordpress_installer --category=Whostmgr --event=Accounts::Create --stage=post # Configuration WORDPRESS_PLAN="wordpress-plan" # Change this to your specific plan name LOG_FILE="/var/log/cpanel_wordpress_auto_install.log" WP_VERSION="latest" WP_ADMIN_USER="admin" WP_ADMIN_EMAIL="[email protected]" # Change to your email # Function to log messages log_message() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" } # Function to generate random password generate_password() { openssl rand -base64 32 | tr -d "=+/" | cut -c1-16 } # Function to download and extract WordPress download_wordpress() { local domain_path="$1" local temp_dir="/tmp/wp_install_$$" mkdir -p "$temp_dir" cd "$temp_dir" # Download WordPress wget -q "https://wordpress.org/latest.tar.gz" -O wordpress.tar.gz if [ $? -eq 0 ]; then tar -xzf wordpress.tar.gz cp -r wordpress/* "$domain_path/" chown -R "$username:$username" "$domain_path/" chmod -R 755 "$domain_path/" rm -rf "$temp_dir" return 0 else log_message "ERROR: Failed to download WordPress for $domain" rm -rf "$temp_dir" return 1 fi } # Function to create WordPress database and user create_wp_database() { local db_name="${username}_wp" local db_user="${username}_wp" local db_pass="$1" # Create database mysql -e "CREATE DATABASE IF NOT EXISTS \`${db_name}\`;" # Create user and grant privileges mysql -e "CREATE USER IF NOT EXISTS '${db_user}'@'localhost' IDENTIFIED BY '${db_pass}';" mysql -e "GRANT ALL PRIVILEGES ON \`${db_name}\`.* TO '${db_user}'@'localhost';" mysql -e "FLUSH PRIVILEGES;" echo "$db_name:$db_user:$db_pass" } # Function to configure WordPress configure_wordpress() { local domain_path="$1" local db_info="$2" IFS=':' read -r db_name db_user db_pass <<< "$db_info" cd "$domain_path" # Create wp-config.php from sample cp wp-config-sample.php wp-config.php # Configure database settings sed -i "s/database_name_here/$db_name/" wp-config.php sed -i "s/username_here/$db_user/" wp-config.php sed -i "s/password_here/$db_pass/" wp-config.php sed -i "s/localhost/localhost/" wp-config.php # Generate and set security keys local keys=$(curl -s https://api.wordpress.org/secret-key/1.1/salt/) sed -i "/AUTH_KEY/,/NONCE_SALT/d" wp-config.php sed -i "/<?php/r /dev/stdin" wp-config.php <<< "$keys" # Set file permissions chown "$username:$username" wp-config.php chmod 644 wp-config.php } # Function to complete WordPress installation via WP-CLI complete_wp_installation() { local domain_path="$1" local site_url="$2" local wp_admin_pass="$3" cd "$domain_path" # Install WP-CLI if not present if [ ! -f /usr/local/bin/wp ]; then wget -q https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -O /usr/local/bin/wp chmod +x /usr/local/bin/wp fi # Complete WordPress installation sudo -u "$username" /usr/local/bin/wp core install \ --url="$site_url" \ --title="Welcome to WordPress" \ --admin_user="$WP_ADMIN_USER" \ --admin_password="$wp_admin_pass" \ --admin_email="$WP_ADMIN_EMAIL" \ --path="$domain_path" return $? } # Main script execution starts here log_message "Hook triggered for account creation" # Read input from cPanel hook while read line; do if [[ $line == user=* ]]; then username=${line#user=} elif [[ $line == domain=* ]]; then domain=${line#domain=} elif [[ $line == plan=* ]]; then plan=${line#plan=} elif [[ $line == homedir=* ]]; then homedir=${line#homedir=} fi done log_message "Processing account: User=$username, Domain=$domain, Plan=$plan" # Check if this account is on the WordPress plan if [ "$plan" != "$WORDPRESS_PLAN" ]; then log_message "Account $username is not on WordPress plan ($plan != $WORDPRESS_PLAN). Skipping WordPress installation." exit 0 fi log_message "Starting WordPress installation for $username on domain $domain" # Set paths domain_path="$homedir/public_html" site_url="http://$domain" # Generate passwords db_password=$(generate_password) wp_admin_password=$(generate_password) # Create WordPress database log_message "Creating database for WordPress..." db_info=$(create_wp_database "$db_password") if [ $? -eq 0 ]; then log_message "Database created successfully" else log_message "ERROR: Failed to create database for $domain" exit 1 fi # Download and extract WordPress log_message "Downloading WordPress..." if download_wordpress "$domain_path"; then log_message "WordPress downloaded and extracted successfully" else log_message "ERROR: Failed to download WordPress for $domain" exit 1 fi # Configure WordPress log_message "Configuring WordPress..." configure_wordpress "$domain_path" "$db_info" # Complete installation using WP-CLI log_message "Completing WordPress installation..." if complete_wp_installation "$domain_path" "$site_url" "$wp_admin_password"; then log_message "WordPress installation completed successfully for $domain" # Save credentials to a file for the user credentials_file="$homedir/wordpress_credentials.txt" cat > "$credentials_file" << EOF WordPress Installation Complete! Site URL: $site_url Admin URL: $site_url/wp-admin Admin Username: $WP_ADMIN_USER Admin Password: $wp_admin_password Database Name: $(echo $db_info | cut -d: -f1) Database User: $(echo $db_info | cut -d: -f2) Database Password: $(echo $db_info | cut -d: -f3) Generated on: $(date) EOF chown "$username:$username" "$credentials_file" chmod 600 "$credentials_file" log_message "Credentials saved to $credentials_file" # Send email notification (optional) if command -v mail >/dev/null 2>&1; then mail -s "WordPress Installation Complete - $domain" "$WP_ADMIN_EMAIL" < "$credentials_file" log_message "Email notification sent to $WP_ADMIN_EMAIL" fi else log_message "ERROR: Failed to complete WordPress installation for $domain" exit 1 fi log_message "WordPress auto-installation process completed for $domain" exit 0