Automatically Installing WordPress on a New cPanel Account

5/5 - (2 votes)

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

 

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top