Updated install shell script
parent
bebc55572d
commit
16375b89ff
|
@ -1,246 +1,377 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Script to automate WordPress installation.
|
||||||
|
# Includes dependency checks, WP-CLI installation, database setup,
|
||||||
|
# WordPress core installation, and configuration.
|
||||||
|
#
|
||||||
|
|
||||||
# Exit on error
|
# --- Configuration ---
|
||||||
|
|
||||||
|
# Exit immediately if a command exits with a non-zero status.
|
||||||
set -e
|
set -e
|
||||||
|
# Treat unset variables as an error when substituting.
|
||||||
|
set -u
|
||||||
|
# Pipe commands return the exit status of the last command in the pipe
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
# Colors for output
|
# Colors for output messages
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
# Default values for WordPress admin
|
# --- Default Values ---
|
||||||
WP_ADMIN_USER="admin"
|
# Avoid insecure defaults. Consider making these mandatory or generating random ones.
|
||||||
WP_ADMIN_PASS="admin"
|
# Leaving them blank to force user input or argument passing.
|
||||||
WP_ADMIN_EMAIL="admin@example.com"
|
WP_ADMIN_USER=""
|
||||||
|
WP_ADMIN_PASS=""
|
||||||
|
WP_ADMIN_EMAIL=""
|
||||||
|
WP_ROOT="/var/www/webroot/ROOT" # Default WordPress root directory
|
||||||
|
DOMAIN="" # Domain will be determined or required
|
||||||
|
DB_HOST="127.0.0.1"
|
||||||
|
DB_ROOT_USER="root"
|
||||||
|
DB_ROOT_PASS="" # Require user to provide this for security
|
||||||
|
SKIP_DB_ROOT_RESET="false" # By default, perform the root password reset (use --skip-db-root-reset to disable)
|
||||||
|
WEB_USER="litespeed" # Web server user (e.g., www-data, apache, nginx)
|
||||||
|
WEB_GROUP="litespeed" # Web server group
|
||||||
|
|
||||||
# Function to display usage
|
# --- Helper Functions ---
|
||||||
usage() {
|
|
||||||
echo "Usage: $0 [options]"
|
# Print informational messages
|
||||||
echo ""
|
info() {
|
||||||
echo "Options:"
|
printf "${BLUE}[INFO] %s${NC}\n" "$@"
|
||||||
echo " --wpusername=USERNAME WordPress admin username (default: admin)"
|
}
|
||||||
echo " --wppassword=PASSWORD WordPress admin password (default: admin)"
|
|
||||||
echo " --wpemail=EMAIL WordPress admin email (default: admin@example.com)"
|
# Print success messages
|
||||||
echo " -h, --help Display this help message"
|
success() {
|
||||||
echo ""
|
printf "${GREEN}[SUCCESS] %s${NC}\n" "$@"
|
||||||
echo "Example:"
|
}
|
||||||
echo " $0 --wpusername=myusername --wppassword=mypassword123 --wpemail=myemail@domain.com"
|
|
||||||
|
# Print warning messages
|
||||||
|
warning() {
|
||||||
|
printf "${YELLOW}[WARNING] %s${NC}\n" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print error messages and exit
|
||||||
|
error_exit() {
|
||||||
|
printf "${RED}[ERROR] %s${NC}\n" "$@" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse command line arguments
|
# Function to display usage information
|
||||||
while [ $# -gt 0 ]; do
|
usage() {
|
||||||
|
printf "Usage: %s [OPTIONS]\n" "$0"
|
||||||
|
printf "\n"
|
||||||
|
printf "Automates the installation of WordPress.\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "Required Options:\n"
|
||||||
|
printf " --wpusername=USERNAME WordPress admin username (mandatory)\n"
|
||||||
|
printf " --wppassword=PASSWORD WordPress admin password (mandatory)\n"
|
||||||
|
printf " --wpemail=EMAIL WordPress admin email (mandatory)\n"
|
||||||
|
printf " --dbrootpass=PASSWORD Current MySQL/MariaDB root password (mandatory unless resetting)\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "Optional Options:\n"
|
||||||
|
printf " --wproot=PATH WordPress installation directory (default: %s)\n" "$WP_ROOT"
|
||||||
|
printf " --domain=DOMAIN Domain name for the site (default: auto-detected from hostname)\n"
|
||||||
|
printf " --webuser=USER Web server user (default: %s)\n" "$WEB_USER"
|
||||||
|
printf " --webgroup=GROUP Web server group (default: %s)\n" "$WEB_GROUP"
|
||||||
|
printf " --dbhost=HOST Database host (default: %s)\n" "$DB_HOST"
|
||||||
|
printf " --reset-db-root-pass Perform the risky root password reset (requires sudo without password)\n"
|
||||||
|
printf " -h, --help Display this help message\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "Example:\n"
|
||||||
|
printf " %s --wpusername=myuser --wppassword='securePass' --wpemail=me@example.com --dbrootpass='currentRootPass'\n" "$0"
|
||||||
|
printf " %s --wpusername=myuser --wppassword='securePass' --wpemail=me@example.com --reset-db-root-pass --domain=example.com\n" "$0"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if a command exists
|
||||||
|
command_exists() {
|
||||||
|
command -v "$1" &> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to generate a random secure password
|
||||||
|
generate_password() {
|
||||||
|
openssl rand -base64 16 # Increased length slightly
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to clean up temporary files
|
||||||
|
cleanup() {
|
||||||
|
info "Cleaning up temporary files..."
|
||||||
|
rm -f "$WP_CLI_CONFIG_PATH"
|
||||||
|
# Add any other cleanup tasks here
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Argument Parsing ---
|
||||||
|
# Using getopt for better argument handling
|
||||||
|
TEMP=$(getopt -o h --longoptions help,wpusername:,wppassword:,wpemail:,wproot:,domain:,dbhost:,dbrootpass:,reset-db-root-pass,webuser:,webgroup: -n "$0" -- "$@")
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
error_exit "Terminating... Invalid arguments."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Note the quotes around "$TEMP": they are essential!
|
||||||
|
eval set -- "$TEMP"
|
||||||
|
unset TEMP
|
||||||
|
|
||||||
|
PERFORM_DB_ROOT_RESET="false"
|
||||||
|
|
||||||
|
while true; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--wpusername=*)
|
--wpusername) WP_ADMIN_USER="$2"; shift 2 ;;
|
||||||
WP_ADMIN_USER="${1#*=}"
|
--wppassword) WP_ADMIN_PASS="$2"; shift 2 ;;
|
||||||
;;
|
--wpemail) WP_ADMIN_EMAIL="$2"; shift 2 ;;
|
||||||
--wppassword=*)
|
--wproot) WP_ROOT="$2"; shift 2 ;;
|
||||||
WP_ADMIN_PASS="${1#*=}"
|
--domain) DOMAIN="$2"; shift 2 ;;
|
||||||
;;
|
--dbhost) DB_HOST="$2"; shift 2 ;;
|
||||||
--wpemail=*)
|
--dbrootpass) DB_ROOT_PASS="$2"; shift 2 ;;
|
||||||
WP_ADMIN_EMAIL="${1#*=}"
|
--reset-db-root-pass) PERFORM_DB_ROOT_RESET="true"; shift 1 ;;
|
||||||
;;
|
--webuser) WEB_USER="$2"; shift 2 ;;
|
||||||
-h|--help)
|
--webgroup) WEB_GROUP="$2"; shift 2 ;;
|
||||||
usage
|
-h|--help) usage ;;
|
||||||
;;
|
--) shift ; break ;; # End of options
|
||||||
*)
|
*) error_exit "Internal error! Unexpected option: $1";;
|
||||||
echo -e "${RED}Error: Invalid option $1${NC}"
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
shift
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# Validate parameters
|
# --- Validation ---
|
||||||
if [[ -z "$WP_ADMIN_USER" ]]; then
|
info "Validating parameters..."
|
||||||
echo -e "${RED}Error: WordPress admin username cannot be empty${NC}"
|
|
||||||
usage
|
if [[ -z "$WP_ADMIN_USER" ]]; then error_exit "WordPress admin username (--wpusername) is required."; fi
|
||||||
|
if [[ -z "$WP_ADMIN_PASS" ]]; then error_exit "WordPress admin password (--wppassword) is required."; fi
|
||||||
|
if [[ -z "$WP_ADMIN_EMAIL" ]]; then error_exit "WordPress admin email (--wpemail) is required."; fi
|
||||||
|
if [[ ! "$WP_ADMIN_EMAIL" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then error_exit "Invalid email format for --wpemail."; fi
|
||||||
|
if [[ "$PERFORM_DB_ROOT_RESET" == "false" && -z "$DB_ROOT_PASS" ]]; then error_exit "Database root password (--dbrootpass) is required unless --reset-db-root-pass is used."; fi
|
||||||
|
if [[ "$PERFORM_DB_ROOT_RESET" == "true" && -n "$DB_ROOT_PASS" ]]; then warning "Both --reset-db-root-pass and --dbrootpass provided. Will perform reset and ignore provided root password."; fi
|
||||||
|
if [[ ! -d "$WP_ROOT" ]]; then error_exit "WordPress root directory '$WP_ROOT' does not exist or is not a directory."; fi
|
||||||
|
if ! id "$WEB_USER" &>/dev/null; then error_exit "Web user '$WEB_USER' does not exist."; fi
|
||||||
|
if ! getent group "$WEB_GROUP" &>/dev/null; then error_exit "Web group '$WEB_GROUP' does not exist."; fi
|
||||||
|
|
||||||
|
# --- Determine Domain ---
|
||||||
|
if [[ -z "$DOMAIN" ]]; then
|
||||||
|
if ! command_exists hostname; then error_exit "'hostname' command not found. Please specify --domain."; fi
|
||||||
|
FULL_HOSTNAME=$(hostname -f)
|
||||||
|
# Attempt to remove common node prefixes, make this more robust if needed
|
||||||
|
DOMAIN=$(echo "$FULL_HOSTNAME" | sed -E 's/^(node[0-9]*-|wp-|web-|host-)//')
|
||||||
|
if [[ -z "$DOMAIN" || "$DOMAIN" == "$FULL_HOSTNAME" ]]; then
|
||||||
|
warning "Could not reliably determine domain from hostname '$FULL_HOSTNAME'. Using it as is."
|
||||||
|
DOMAIN="$FULL_HOSTNAME"
|
||||||
|
fi
|
||||||
|
info "Auto-detected domain: $DOMAIN (Use --domain to override)"
|
||||||
|
else
|
||||||
|
info "Using specified domain: $DOMAIN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "$WP_ADMIN_PASS" ]]; then
|
# --- Dependency Checks ---
|
||||||
echo -e "${RED}Error: WordPress admin password cannot be empty${NC}"
|
info "Checking dependencies..."
|
||||||
usage
|
declare -a dependencies=("php" "mysql" "curl" "openssl" "sudo" "hostname" "sed" "systemctl" "getopt")
|
||||||
|
for cmd in "${dependencies[@]}"; do
|
||||||
|
if ! command_exists "$cmd"; then
|
||||||
|
error_exit "Required command '$cmd' is not installed. Please install it first."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# Specific check for pkill if reset is chosen
|
||||||
|
if [[ "$PERFORM_DB_ROOT_RESET" == "true" ]]; then
|
||||||
|
if ! command_exists pkill; then error_exit "'pkill' command not found, but required for --reset-db-root-pass."; fi
|
||||||
|
if ! command_exists mysqld_safe; then error_exit "'mysqld_safe' command not found, but required for --reset-db-root-pass."; fi
|
||||||
|
fi
|
||||||
|
success "All dependencies found."
|
||||||
|
|
||||||
|
# --- WP-CLI Setup ---
|
||||||
|
WP_CLI_PATH="/usr/local/bin/wp"
|
||||||
|
|
||||||
|
# Check if WP-CLI is installed and executable
|
||||||
|
if ! command_exists wp; then
|
||||||
|
info "WP-CLI not found. Installing WP-CLI..."
|
||||||
|
if ! curl -o wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar; then
|
||||||
|
error_exit "Failed to download WP-CLI."
|
||||||
|
fi
|
||||||
|
chmod +x wp-cli.phar
|
||||||
|
if ! sudo mv wp-cli.phar "$WP_CLI_PATH"; then
|
||||||
|
error_exit "Failed to move WP-CLI to $WP_CLI_PATH. Check sudo permissions."
|
||||||
|
fi
|
||||||
|
# Verify installation
|
||||||
|
if ! command_exists wp; then
|
||||||
|
error_exit "WP-CLI installation failed unexpectedly."
|
||||||
|
fi
|
||||||
|
success "WP-CLI installed successfully to $WP_CLI_PATH"
|
||||||
|
else
|
||||||
|
success "WP-CLI is already installed."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! "$WP_ADMIN_EMAIL" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then
|
# Set up temporary WP-CLI config for HTTP_HOST if needed
|
||||||
echo -e "${RED}Error: Invalid email format${NC}"
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Define WordPress root directory
|
|
||||||
WP_ROOT="/var/www/webroot/ROOT"
|
|
||||||
|
|
||||||
# Get the domain without the node prefix
|
|
||||||
FULL_HOSTNAME=$(hostname -f)
|
|
||||||
DOMAIN=$(echo "$FULL_HOSTNAME" | sed 's/^node[0-9]*-//')
|
|
||||||
|
|
||||||
# Set HTTP_HOST for WP-CLI
|
|
||||||
export WP_CLI_CONFIG_PATH="/tmp/wp-cli-config-$RANDOM.yml"
|
export WP_CLI_CONFIG_PATH="/tmp/wp-cli-config-$RANDOM.yml"
|
||||||
cat > "$WP_CLI_CONFIG_PATH" <<EOF
|
cat > "$WP_CLI_CONFIG_PATH" <<EOF
|
||||||
config create:
|
# Temporary config to help WP-CLI resolve the site URL
|
||||||
extra-php: |
|
# This might not always be necessary depending on server config
|
||||||
\$_SERVER['HTTP_HOST'] = '$DOMAIN';
|
apache_modules:
|
||||||
|
- mod_rewrite
|
||||||
|
_:
|
||||||
|
server:
|
||||||
|
HTTP_HOST: $DOMAIN
|
||||||
|
HTTPS: on # Assume HTTPS
|
||||||
EOF
|
EOF
|
||||||
|
# Set trap to clean up the temp file on exit
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
echo -e "${YELLOW}Starting WordPress installation process...${NC}"
|
# --- Database Setup ---
|
||||||
echo -e "${YELLOW}Using domain: $DOMAIN${NC}"
|
info "Setting up database..."
|
||||||
|
DB_NAME="wpdb_$(openssl rand -hex 4)"
|
||||||
|
DB_USER="wpuser_$(openssl rand -hex 4)"
|
||||||
|
DB_PASSWORD=$(generate_password)
|
||||||
|
|
||||||
# Check if PHP is installed
|
if [[ "$PERFORM_DB_ROOT_RESET" == "true" ]]; then
|
||||||
if ! command -v php &> /dev/null; then
|
# --- Risky Root Password Reset ---
|
||||||
echo -e "${RED}PHP is not installed. Please install PHP first.${NC}"
|
warning "Attempting to reset MariaDB/MySQL root password. This is risky!"
|
||||||
exit 1
|
new_root_password=$(generate_password)
|
||||||
fi
|
info "New root password will be: $new_root_password"
|
||||||
|
|
||||||
# Check if MySQL/MariaDB is installed
|
info "Stopping MariaDB service..."
|
||||||
if ! command -v mysql &> /dev/null; then
|
if ! sudo systemctl stop mariadb; then error_exit "Failed to stop MariaDB service."; fi
|
||||||
echo -e "${RED}MySQL/MariaDB is not installed. Please install MySQL/MariaDB first.${NC}"
|
# Wait a moment to ensure it stopped
|
||||||
exit 1
|
sleep 3
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if WordPress root directory exists
|
info "Starting MariaDB in safe mode (skip-grant-tables)..."
|
||||||
if [ ! -d "$WP_ROOT" ]; then
|
sudo mysqld_safe --skip-grant-tables --skip-networking &
|
||||||
echo -e "${RED}WordPress root directory $WP_ROOT does not exist.${NC}"
|
MYSQLD_SAFE_PID=$!
|
||||||
exit 1
|
# Wait for MariaDB to likely start in safe mode
|
||||||
fi
|
sleep 10 # Increased wait time for reliability
|
||||||
|
|
||||||
# Change to WordPress root directory
|
info "Attempting to reset root password..."
|
||||||
cd "$WP_ROOT"
|
# Try multiple common root user variations
|
||||||
|
if ! sudo mysql --protocol=socket -u root <<-EOF
|
||||||
# Install WP-CLI if not already installed
|
|
||||||
if ! command -v wp &> /dev/null; then
|
|
||||||
echo -e "${YELLOW}Installing WP-CLI...${NC}"
|
|
||||||
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
|
|
||||||
chmod +x wp-cli.phar
|
|
||||||
sudo mv wp-cli.phar /usr/local/bin/wp
|
|
||||||
|
|
||||||
# Verify WP-CLI installation
|
|
||||||
if ! command -v wp &> /dev/null; then
|
|
||||||
echo -e "${RED}Failed to install WP-CLI${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo -e "${GREEN}WP-CLI installed successfully${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}WP-CLI is already installed${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Database Preparation
|
|
||||||
echo -e "${YELLOW}Preparing database...${NC}"
|
|
||||||
|
|
||||||
# Automatically generate a new secure password for the root user
|
|
||||||
new_root_password=$(openssl rand -base64 12)
|
|
||||||
|
|
||||||
# Generate random database name, user, and password for the new database
|
|
||||||
DB_NAME="db_$(openssl rand -hex 4)"
|
|
||||||
DB_USER="user_$(openssl rand -hex 4)"
|
|
||||||
DB_PASSWORD="$(openssl rand -base64 12)"
|
|
||||||
DB_HOST="127.0.0.1"
|
|
||||||
|
|
||||||
echo -e "${YELLOW}New root password will be: $new_root_password${NC}"
|
|
||||||
echo -e "${YELLOW}New database credentials:${NC}"
|
|
||||||
echo -e "Database Name: $DB_NAME"
|
|
||||||
echo -e "Database User: $DB_USER"
|
|
||||||
echo -e "Database Password: $DB_PASSWORD"
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Attempting to stop the MariaDB service...${NC}"
|
|
||||||
# Stop the MariaDB service
|
|
||||||
sudo systemctl stop mariadb
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Starting MariaDB in safe mode...${NC}"
|
|
||||||
# Start MariaDB in safe mode with no networking and no grants
|
|
||||||
sudo mysqld_safe --skip-grant-tables --skip-networking &
|
|
||||||
|
|
||||||
# Wait for MariaDB to fully start in safe mode
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Resetting the root password...${NC}"
|
|
||||||
# Reset the root password in safe mode
|
|
||||||
sudo mysql -u root <<EOF
|
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
ALTER USER 'root'@'localhost' IDENTIFIED BY '$new_root_password';
|
ALTER USER 'root'@'localhost' IDENTIFIED BY '$new_root_password';
|
||||||
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY '$new_root_password';
|
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY '$new_root_password';
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
|
EXIT
|
||||||
EOF
|
EOF
|
||||||
|
then
|
||||||
# Check if the password reset was successful
|
warning "Failed initial root password reset attempt. Trying alternative command..."
|
||||||
if [ $? -eq 0 ]; then
|
# Fallback for older MySQL/MariaDB versions
|
||||||
echo -e "${GREEN}Root password reset successful.${NC}"
|
if ! sudo mysql --protocol=socket -u root <<-EOF
|
||||||
else
|
|
||||||
echo -e "${RED}Failed to reset the root password. Exiting.${NC}"
|
|
||||||
sudo pkill -f mariadbd
|
|
||||||
sudo pkill -f mysqld_safe
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Stopping the MariaDB safe mode process...${NC}"
|
|
||||||
# Terminate the MariaDB safe mode processes
|
|
||||||
sudo pkill -f mysqld_safe
|
|
||||||
sleep 2
|
|
||||||
sudo pkill -f mariadbd
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Starting the MariaDB service normally...${NC}"
|
|
||||||
# Start the MariaDB service normally
|
|
||||||
sudo systemctl start mariadb
|
|
||||||
|
|
||||||
# Check if MariaDB started successfully
|
|
||||||
if sudo systemctl is-active --quiet mariadb; then
|
|
||||||
echo -e "${GREEN}MariaDB service is running. Root password has been reset.${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}Failed to start MariaDB service. Please check the service status manually.${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Introduce a delay to allow MariaDB to fully initialize
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# Create MySQL database and user with the new root password
|
|
||||||
echo -e "${YELLOW}Creating MySQL database and user...${NC}"
|
|
||||||
mysql -u root -p"$new_root_password" <<EOF
|
|
||||||
CREATE DATABASE ${DB_NAME};
|
|
||||||
CREATE USER '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASSWORD}';
|
|
||||||
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASSWORD}';
|
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
|
UPDATE mysql.user SET Password=PASSWORD('$new_root_password') WHERE User='root' AND Host='localhost';
|
||||||
|
UPDATE mysql.user SET Password=PASSWORD('$new_root_password') WHERE User='root' AND Host='127.0.0.1';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
EXIT
|
||||||
EOF
|
EOF
|
||||||
|
then
|
||||||
|
warning "Both root password reset methods failed. Trying grant table directly (less reliable)."
|
||||||
|
# This might be needed on some very old or strangely configured systems
|
||||||
|
if ! sudo mysql --protocol=socket -u mysql <<-EOF
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
UPDATE mysql.user SET authentication_string=PASSWORD('$new_root_password') WHERE User='root';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
EXIT
|
||||||
|
EOF
|
||||||
|
then
|
||||||
|
error_exit "All attempts to reset the root password failed. Check MySQL/MariaDB logs. Manual intervention required."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
success "Root password likely reset in safe mode."
|
||||||
|
|
||||||
# Check if the database and user creation was successful
|
info "Stopping MariaDB safe mode process..."
|
||||||
if [ $? -eq 0 ]; then
|
# Attempt to kill the background mysqld_safe process gracefully first, then force if needed
|
||||||
echo -e "${GREEN}Database ${DB_NAME} and user ${DB_USER} created successfully.${NC}"
|
sudo kill $MYSQLD_SAFE_PID || true # Try killing the specific PID
|
||||||
|
sleep 2
|
||||||
|
sudo pkill -f mysqld_safe || true # Broader attempt
|
||||||
|
sleep 2
|
||||||
|
sudo pkill -f mariadbd || sudo pkill -f mysqld || true # Kill any lingering daemons
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
info "Starting MariaDB service normally..."
|
||||||
|
if ! sudo systemctl start mariadb; then error_exit "Failed to start MariaDB service after password reset."; fi
|
||||||
|
sleep 5 # Allow time for service to initialize
|
||||||
|
|
||||||
|
if ! sudo systemctl is-active --quiet mariadb; then error_exit "MariaDB service failed to start or become active. Check service status."; fi
|
||||||
|
success "MariaDB service started successfully with new root password."
|
||||||
|
DB_ROOT_PASS="$new_root_password" # Use the newly set password
|
||||||
else
|
else
|
||||||
echo -e "${RED}Failed to create database or user. Please check the MySQL status manually.${NC}"
|
info "Using provided root password to create database and user."
|
||||||
exit 1
|
# Test connection with provided root password
|
||||||
|
if ! mysql -u "$DB_ROOT_USER" -p"$DB_ROOT_PASS" -h "$DB_HOST" -e "SELECT 1;" &> /dev/null; then
|
||||||
|
error_exit "Failed to connect to database using provided root credentials. Check user, password, and host."
|
||||||
|
fi
|
||||||
|
success "Database root connection successful."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# --- Create WordPress Database and User ---
|
||||||
|
info "Creating WordPress database '$DB_NAME' and user '$DB_USER'..."
|
||||||
|
# Use printf for safer password injection into the command
|
||||||
|
SQL_COMMAND=$(printf "CREATE DATABASE IF NOT EXISTS %s CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS '%s'@'%s' IDENTIFIED BY '%s'; GRANT ALL PRIVILEGES ON %s.* TO '%s'@'%s'; FLUSH PRIVILEGES;" \
|
||||||
|
"$DB_NAME" "$DB_USER" "$DB_HOST" "$DB_PASSWORD" "$DB_NAME" "$DB_USER" "$DB_HOST")
|
||||||
|
|
||||||
|
if ! mysql -u "$DB_ROOT_USER" -p"$DB_ROOT_PASS" -h "$DB_HOST" -e "$SQL_COMMAND"; then
|
||||||
|
error_exit "Failed to create WordPress database or user. Check MySQL/MariaDB logs and permissions."
|
||||||
|
fi
|
||||||
|
success "Database and user created successfully."
|
||||||
|
|
||||||
|
# --- WordPress Installation ---
|
||||||
|
info "Navigating to WordPress root: $WP_ROOT"
|
||||||
|
cd "$WP_ROOT" || error_exit "Failed to change directory to $WP_ROOT"
|
||||||
|
|
||||||
# Backup existing wp-config.php if it exists
|
# Backup existing wp-config.php if it exists
|
||||||
if [ -f "wp-config.php" ]; then
|
if [[ -f "wp-config.php" ]]; then
|
||||||
echo -e "${YELLOW}Backing up existing wp-config.php...${NC}"
|
BACKUP_NAME="wp-config.php.bak.$(date +%Y%m%d%H%M%S)"
|
||||||
cp wp-config.php wp-config.php.bak
|
info "Backing up existing wp-config.php to $BACKUP_NAME"
|
||||||
|
cp wp-config.php "$BACKUP_NAME"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Download WordPress core if not already present
|
# Download WordPress core files if necessary (index.php is a good indicator)
|
||||||
if [ ! -f "index.php" ] && [ ! -d "wp-admin" ]; then
|
# Run wp commands as the web user if possible, falling back to --allow-root if needed
|
||||||
echo -e "${YELLOW}WordPress files not detected. Downloading WordPress core...${NC}"
|
WP_RUN_ARGS=("--path=$WP_ROOT")
|
||||||
wp core download --skip-content --allow-root
|
# Determine if sudo is needed to run as web user
|
||||||
|
SUDO_CMD=""
|
||||||
# Now WordPress core installation will handle theme installation automatically
|
if [[ "$(id -u)" -ne "$(id -u "$WEB_USER")" ]]; then
|
||||||
# since we removed the --skip-themes flag from the wp core install command
|
SUDO_CMD="sudo -u $WEB_USER"
|
||||||
echo -e "${GREEN}WordPress core downloaded successfully${NC}"
|
# Check if we can sudo without password, otherwise need --allow-root
|
||||||
|
if ! sudo -n -u "$WEB_USER" true &>/dev/null; then
|
||||||
|
warning "Cannot sudo to '$WEB_USER' without a password. Using --allow-root for WP-CLI commands."
|
||||||
|
SUDO_CMD="" # Clear sudo command
|
||||||
|
WP_RUN_ARGS+=("--allow-root")
|
||||||
|
else
|
||||||
|
info "Running WP-CLI commands as user '$WEB_USER'."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ ! -f "index.php" || ! -d "wp-admin" ]]; then
|
||||||
|
info "WordPress core files not found. Downloading..."
|
||||||
|
if ! $SUDO_CMD wp core download "${WP_RUN_ARGS[@]}" --skip-content --version=latest; then
|
||||||
|
error_exit "Failed to download WordPress core files."
|
||||||
|
fi
|
||||||
|
success "WordPress core downloaded."
|
||||||
else
|
else
|
||||||
echo -e "${GREEN}WordPress files already exist. Skipping download.${NC}"
|
info "WordPress files already exist. Skipping download."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Immediate check to directly create wp-config.php regardless of previous steps
|
# --- Create wp-config.php ---
|
||||||
# This is a critical fix to ensure wp-config.php exists before installation continues
|
# Using wp cli command is generally preferred, but manual creation is more robust if WP-CLI has issues.
|
||||||
echo -e "${YELLOW}CRITICAL FIX: Directly creating wp-config.php to prevent errors...${NC}"
|
# We'll stick to the manual creation from your original script as it included specific fixes.
|
||||||
if [ ! -f "wp-config.php" ]; then
|
info "Creating wp-config.php..."
|
||||||
echo -e "${RED}wp-config.php is still missing. Creating it directly...${NC}"
|
# Generate Salts using WP-CLI if possible, otherwise fallback to openssl
|
||||||
cat > wp-config.php <<EOF
|
SALTS=$($SUDO_CMD wp config salt generate --raw "${WP_RUN_ARGS[@]}" 2>/dev/null || {
|
||||||
<?php
|
warning "Could not generate salts using WP-CLI, falling back to openssl (less standard format)."
|
||||||
define( 'WP_CACHE', true );
|
echo "define( 'AUTH_KEY', '$(generate_password)' );"
|
||||||
|
echo "define( 'SECURE_AUTH_KEY', '$(generate_password)' );"
|
||||||
|
echo "define( 'LOGGED_IN_KEY', '$(generate_password)' );"
|
||||||
|
echo "define( 'NONCE_KEY', '$(generate_password)' );"
|
||||||
|
echo "define( 'AUTH_SALT', '$(generate_password)' );"
|
||||||
|
echo "define( 'SECURE_AUTH_SALT', '$(generate_password)' );"
|
||||||
|
echo "define( 'LOGGED_IN_SALT', '$(generate_password)' );"
|
||||||
|
echo "define( 'NONCE_SALT', '$(generate_password)' );"
|
||||||
|
})
|
||||||
|
|
||||||
|
# Use cat with heredoc for wp-config.php creation
|
||||||
|
cat > wp-config.php <<EOF
|
||||||
|
<?php
|
||||||
/**
|
/**
|
||||||
* The base configuration for WordPress
|
* The base configuration for WordPress
|
||||||
*
|
*
|
||||||
|
* @link https://wordpress.org/support/article/editing-wp-config-php/
|
||||||
|
*
|
||||||
* @package WordPress
|
* @package WordPress
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -258,105 +389,143 @@ define( 'DB_PASSWORD', '${DB_PASSWORD}' );
|
||||||
define( 'DB_HOST', '${DB_HOST}' );
|
define( 'DB_HOST', '${DB_HOST}' );
|
||||||
|
|
||||||
/** Database charset to use in creating database tables. */
|
/** Database charset to use in creating database tables. */
|
||||||
define( 'DB_CHARSET', 'utf8' );
|
define( 'DB_CHARSET', 'utf8mb4' ); // Use utf8mb4 for better character support
|
||||||
|
|
||||||
/** The database collate type. Don't change this if in doubt. */
|
/** The database collate type. Don't change this if in doubt. */
|
||||||
define( 'DB_COLLATE', '' );
|
define( 'DB_COLLATE', '' );
|
||||||
|
|
||||||
/**
|
/**#@+
|
||||||
* Authentication unique keys and salts.
|
* Authentication unique keys and salts.
|
||||||
|
* Generate these at: https://api.wordpress.org/secret-key/1.1/salt/
|
||||||
|
* You can change these at any point to invalidate all existing cookies. This will force all users to have to log in again.
|
||||||
*/
|
*/
|
||||||
define( 'AUTH_KEY', '$(openssl rand -base64 48)' );
|
${SALTS}
|
||||||
define( 'SECURE_AUTH_KEY', '$(openssl rand -base64 48)' );
|
/**#@-*/
|
||||||
define( 'LOGGED_IN_KEY', '$(openssl rand -base64 48)' );
|
|
||||||
define( 'NONCE_KEY', '$(openssl rand -base64 48)' );
|
|
||||||
define( 'AUTH_SALT', '$(openssl rand -base64 48)' );
|
|
||||||
define( 'SECURE_AUTH_SALT', '$(openssl rand -base64 48)' );
|
|
||||||
define( 'LOGGED_IN_SALT', '$(openssl rand -base64 48)' );
|
|
||||||
define( 'NONCE_SALT', '$(openssl rand -base64 48)' );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WordPress database table prefix.
|
* WordPress database table prefix.
|
||||||
|
* You can have multiple installations in one database if you give each
|
||||||
|
* a unique prefix. Only numbers, letters, and underscores please!
|
||||||
*/
|
*/
|
||||||
\$table_prefix = 'wp_';
|
\$table_prefix = 'wp_';
|
||||||
|
|
||||||
/* Custom values */
|
|
||||||
define( 'WP_AUTO_UPDATE_CORE', false );
|
|
||||||
define( 'WP_HOME', 'https://${DOMAIN}' );
|
|
||||||
define( 'WP_SITEURL', 'https://${DOMAIN}' );
|
|
||||||
define( 'WP_MEMORY_LIMIT', '256M' );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For developers: WordPress debugging mode.
|
* For developers: WordPress debugging mode.
|
||||||
|
* Change this to true to enable the display of notices during development.
|
||||||
|
* It is strongly recommended that plugin and theme developers use WP_DEBUG
|
||||||
|
* in their development environments.
|
||||||
|
* For information on other constants that can be used for debugging,
|
||||||
|
* visit the documentation.
|
||||||
|
* @link https://wordpress.org/support/article/debugging-in-wordpress/
|
||||||
*/
|
*/
|
||||||
define( 'WP_DEBUG', false );
|
define( 'WP_DEBUG', false );
|
||||||
|
|
||||||
// Fix for HTTP_HOST issue when running WP-CLI
|
/* Add any custom values between this line and the "stop editing" line. */
|
||||||
if (!isset(\$_SERVER['HTTP_HOST'])) {
|
|
||||||
|
define( 'WP_MEMORY_LIMIT', '256M' );
|
||||||
|
define( 'WP_AUTO_UPDATE_CORE', false ); // Or 'minor' or true
|
||||||
|
|
||||||
|
// Define site URL and home URL (ensure protocol matches server setup)
|
||||||
|
define( 'WP_HOME', 'https://${DOMAIN}' );
|
||||||
|
define( 'WP_SITEURL', 'https://${DOMAIN}' );
|
||||||
|
|
||||||
|
// If using a reverse proxy, this might be needed:
|
||||||
|
// if (isset(\$_SERVER['HTTP_X_FORWARDED_PROTO']) && \$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
||||||
|
// \$_SERVER['HTTPS'] = 'on';
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Fix missing HTTP_HOST for CLI operations
|
||||||
|
if ( defined( 'WP_CLI' ) && WP_CLI && ! isset( \$_SERVER['HTTP_HOST'] ) ) {
|
||||||
\$_SERVER['HTTP_HOST'] = '${DOMAIN}';
|
\$_SERVER['HTTP_HOST'] = '${DOMAIN}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* That's all, stop editing! Happy publishing. */
|
||||||
|
|
||||||
/** Absolute path to the WordPress directory. */
|
/** Absolute path to the WordPress directory. */
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
define( 'ABSPATH', __DIR__ . '/' );
|
define( 'ABSPATH', __DIR__ . '/' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets up WordPress vars and included files. */
|
/** Sets up WordPress vars and included files. */
|
||||||
require_once ABSPATH . 'wp-settings.php';
|
require_once ABSPATH . 'wp-settings.php';
|
||||||
EOF
|
EOF
|
||||||
echo -e "${GREEN}wp-config.php created directly with fixed method${NC}"
|
|
||||||
|
if [[ ! -f "wp-config.php" ]]; then
|
||||||
# Ensure file was created and is readable
|
error_exit "Failed to create wp-config.php file."
|
||||||
ls -la wp-config.php
|
|
||||||
chmod 644 wp-config.php
|
|
||||||
chown litespeed:litespeed wp-config.php
|
|
||||||
echo -e "${GREEN}wp-config.php permissions fixed${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}wp-config.php already exists. Continuing...${NC}"
|
|
||||||
fi
|
fi
|
||||||
|
success "wp-config.php created successfully."
|
||||||
|
|
||||||
# Skip the normal wp-config.php creation process since we've already handled it directly
|
# --- Set Permissions ---
|
||||||
echo -e "${YELLOW}Continuing with WordPress installation...${NC}"
|
info "Setting file permissions..."
|
||||||
|
# Set ownership first
|
||||||
|
if ! sudo chown -R "${WEB_USER}:${WEB_GROUP}" "$WP_ROOT"; then
|
||||||
|
error_exit "Failed to set ownership on $WP_ROOT."
|
||||||
|
fi
|
||||||
|
# Set directory and file permissions
|
||||||
|
# Ensure the script runner has write access to the directory to run find
|
||||||
|
cd "$WP_ROOT" || error_exit "Failed to cd into $WP_ROOT before setting permissions"
|
||||||
|
if ! sudo find . -type d -exec chmod 755 {} \; ; then
|
||||||
|
warning "Could not set directory permissions using find. Check sudo permissions."
|
||||||
|
fi
|
||||||
|
if ! sudo find . -type f -exec chmod 644 {} \; ; then
|
||||||
|
warning "Could not set file permissions using find. Check sudo permissions."
|
||||||
|
fi
|
||||||
|
# Ensure wp-config.php is readable by the web server, but not world-writable
|
||||||
|
if ! sudo chmod 640 wp-config.php; then # More secure permission
|
||||||
|
warning "Could not set specific permissions on wp-config.php."
|
||||||
|
fi
|
||||||
|
success "File permissions set."
|
||||||
|
|
||||||
# Set proper permissions
|
# --- WordPress Core Installation ---
|
||||||
echo -e "${YELLOW}Setting proper permissions...${NC}"
|
# Check if WordPress is already installed before attempting installation
|
||||||
sudo chown -R litespeed:litespeed "$WP_ROOT"
|
if ! $SUDO_CMD wp core is-installed "${WP_RUN_ARGS[@]}"; then
|
||||||
sudo find "$WP_ROOT" -type d -exec chmod 755 {} \;
|
info "WordPress is not installed. Proceeding with installation..."
|
||||||
sudo find "$WP_ROOT" -type f -exec chmod 644 {} \;
|
if ! $SUDO_CMD wp core install \
|
||||||
|
|
||||||
# Install WordPress if not already installed
|
|
||||||
if ! wp core is-installed --allow-root; then
|
|
||||||
echo -e "${YELLOW}Installing WordPress...${NC}"
|
|
||||||
wp core install \
|
|
||||||
--url="https://$DOMAIN" \
|
--url="https://$DOMAIN" \
|
||||||
--title="My WordPress Site" \
|
--title="My WordPress Site on $DOMAIN" \
|
||||||
--admin_user="$WP_ADMIN_USER" \
|
--admin_user="$WP_ADMIN_USER" \
|
||||||
--admin_password="$WP_ADMIN_PASS" \
|
--admin_password="$WP_ADMIN_PASS" \
|
||||||
--admin_email="$WP_ADMIN_EMAIL" \
|
--admin_email="$WP_ADMIN_EMAIL" \
|
||||||
--skip-plugins \
|
--skip-email \
|
||||||
--allow-root
|
"${WP_RUN_ARGS[@]}"; then # Added skip-email
|
||||||
|
error_exit "WordPress core installation failed."
|
||||||
|
fi
|
||||||
|
|
||||||
# Remove default plugins if any were installed
|
info "Removing default plugins (Akismet, Hello Dolly)..."
|
||||||
echo -e "${YELLOW}Removing default plugins...${NC}"
|
$SUDO_CMD wp plugin delete akismet hello "${WP_RUN_ARGS[@]}" --quiet || warning "Could not delete default plugins."
|
||||||
wp plugin delete hello akismet --allow-root
|
|
||||||
|
success "WordPress installed successfully."
|
||||||
else
|
else
|
||||||
echo -e "${GREEN}WordPress is already installed.${NC}"
|
info "WordPress is already installed."
|
||||||
# Update site URL if needed
|
# Optionally update URL if needed (be careful with this)
|
||||||
wp option update siteurl "https://$DOMAIN" --allow-root
|
# info "Verifying site URL..."
|
||||||
wp option update home "https://$DOMAIN" --allow-root
|
# $SUDO_CMD wp option update siteurl "https://$DOMAIN" "${WP_RUN_ARGS[@]}"
|
||||||
|
# $SUDO_CMD wp option update home "https://$DOMAIN" "${WP_RUN_ARGS[@]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${GREEN}WordPress installation completed successfully!${NC}"
|
# --- Final Summary ---
|
||||||
echo -e "${YELLOW}Database Credentials:${NC}"
|
success "WordPress setup completed!"
|
||||||
echo -e "Database Name: $DB_NAME"
|
printf "\n--- ${YELLOW}Installation Summary${NC} ---\n"
|
||||||
echo -e "Database User: $DB_USER"
|
printf "Site URL: ${GREEN}https://%s${NC}\n" "$DOMAIN"
|
||||||
echo -e "Database Password: $DB_PASSWORD"
|
printf "WP Root: ${GREEN}%s${NC}\n" "$WP_ROOT"
|
||||||
echo -e "Database Host: $DB_HOST"
|
printf "Web User: ${GREEN}%s${NC}\n" "$WEB_USER"
|
||||||
echo -e "${YELLOW}Admin login:${NC}"
|
printf "Web Group: ${GREEN}%s${NC}\n" "$WEB_GROUP"
|
||||||
echo -e "Username: $WP_ADMIN_USER"
|
printf "\n"
|
||||||
echo -e "Password: $WP_ADMIN_PASS"
|
printf "${YELLOW}Admin Credentials:${NC}\n"
|
||||||
echo -e "Email: $WP_ADMIN_EMAIL"
|
printf " Username: ${GREEN}%s${NC}\n" "$WP_ADMIN_USER"
|
||||||
echo -e "${YELLOW}Site URL: https://$DOMAIN${NC}"
|
printf " Password: ${YELLOW}%s${NC} (Keep this safe!)\n" "$WP_ADMIN_PASS"
|
||||||
|
printf " Email: ${GREEN}%s${NC}\n" "$WP_ADMIN_EMAIL"
|
||||||
|
printf "\n"
|
||||||
|
printf "${YELLOW}Database Credentials:${NC}\n"
|
||||||
|
printf " Database Name: ${GREEN}%s${NC}\n" "$DB_NAME"
|
||||||
|
printf " Username: ${GREEN}%s${NC}\n" "$DB_USER"
|
||||||
|
printf " Password: ${YELLOW}%s${NC} (Keep this safe!)\n" "$DB_PASSWORD"
|
||||||
|
printf " Host: ${GREEN}%s${NC}\n" "$DB_HOST"
|
||||||
|
if [[ "$PERFORM_DB_ROOT_RESET" == "true" ]]; then
|
||||||
|
printf "\n${RED}IMPORTANT: The MySQL/MariaDB root password was reset to:${NC}\n"
|
||||||
|
printf " Root Password: ${YELLOW}%s${NC}\n" "$DB_ROOT_PASS"
|
||||||
|
fi
|
||||||
|
printf "---------------------------\n"
|
||||||
|
|
||||||
# Clean up the temporary WP-CLI config
|
exit 0
|
||||||
rm -f "$WP_CLI_CONFIG_PATH"
|
|
Loading…
Reference in New Issue