From 1e94746f13f6655925a054c8539ea119bbbe5000 Mon Sep 17 00:00:00 2001 From: allan Date: Thu, 23 Oct 2025 15:46:59 +0200 Subject: [PATCH] initial commit --- LICENSE | 21 ++++ README.md | 174 +++++++++++++++++++++++++++++++++ last-tested | 4 + wordpressinstall | 243 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 442 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 last-tested create mode 100755 wordpressinstall diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3eaaa81 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Allan Christensen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf0df70 --- /dev/null +++ b/README.md @@ -0,0 +1,174 @@ +# WordPress for Ubuntu 24.04 Server +[![OS](https://img.shields.io/badge/ubuntu-24.04-E95420)](#) +[![Shell](https://img.shields.io/badge/shell-bash-121011)](#) +[![WebServer](https://img.shields.io/badge/server-nginx-009639)](#) +[![PHP](https://img.shields.io/badge/php-fpm-777BB4)](#) +[![DB](https://img.shields.io/badge/server-mariadb-003545)](#) +[![App](https://img.shields.io/badge/app-wordpress-21759B)](#) +[![License](https://img.shields.io/badge/License-MIT-green)](./LICENSE) + +Installs and configures the **latest stable release of WordPress** on Ubuntu 24.04 Server. + +This is a **production-focused installer**, not a demo. + +It assumes Nginx, PHP-FPM, and MariaDB are already installed and running. + +--- + +## Related Installers + +If you don’t have the required components, you can use these compatible installers: + +- [Nginx + PHP-FPM Installer](https://git.x-files.dk/webserver/nginx-ubuntu) +- [MariaDB Installer](https://git.x-files.dk/database/mariadb-ubuntu) + +--- + +### Download the Script + +Clone this repository to your server: + +``` +git clone https://git.x-files.dk/webapps/wordpress-ubuntu.git +``` + +``` +cd wordpress-ubuntu +``` + +### Usage + +Run the script using: + +``` +sudo ./wordpressinstall -n -d -u -p [options] +``` + +### Examples + +The installer automatically detects if socket authentication is active. +Only include `-m` and `-a` if your MariaDB setup does **not** use socket authentication. + +``` +sudo ./wordpressinstall -n wp.example.com -d wpdb -u wpuser -p wpPass123 +sudo ./wordpressinstall -n wp.example.com -d wpdb -u wpuser -p wpPass123 -m rootpwd +sudo ./wordpressinstall -n wp.example.com -d wpdb -u wpuser -p wpPass123 -a admin -m adminpwd +``` + +### Options + +| Flag | Description | +|------|--------------| +| `-m ` | MariaDB root or admin password — *required only if socket authentication is disabled* | +| `-a ` | Optional MariaDB admin username (defaults to `root` if not specified) | +| `-h`, `--help` | Show the help screen (reflects detected socket status) | + +### Configuration +When installation completes, visit: + +``` +http:///wp-admin/install.php +``` + +Then create your WordPress site title and administrator account. +(Database configuration is already completed by the installer.) + +--- + +### Features + +- Installs and configures WordPress automatically +- Creates the MariaDB database and user +- Generates an Nginx host configuration dynamically +- Integrates runtime WordPress hardening and rate limiting +- Validates Nginx configuration before restarting services +- Detects MariaDB socket or password authentication automatically + +--- + +### Configuration Details + +#### File Locations + +| File | Description | +|------|--------------| +| `/var/www/html/` | WordPress site directory | +| `/etc/nginx/conf.d/.conf` | Generated Nginx host file | +| `/etc/nginx/conf.d/includes/wp-hardening.conf` | WordPress hardening | +| `/etc/nginx/conf.d/wp-rate-limit.conf` | Request rate-limiting | + +--- + +#### Behavior + +- The installer automatically checks for **MariaDB socket authentication**. + If available, it connects locally as `root` (no password). +- If socket authentication is **not detected**, use `-m` (and optionally `-a`) to supply credentials. +- All database commands include `IF NOT EXISTS` logic, making re-runs safe. +- Nginx configuration is validated (`nginx -t`) before restarting services. + +--- + +### Nginx Integration + +The generated Wordpress configuration file listens on port 80. +To enable HTTPS (port 443), use the example provided [here](https://git.x-files.dk/webserver/nginx-snippets/src/branch/main/hostfiles/wordpress.443.conf) + +> **NOTE** +> The file also includes optional caching directives (commented out by default). +> You can enable them to improve load times and performance if needed. +> The lines you are looking for are at the bottom of the generated config file and look like this: +> ``` +> ##### Cache js css static content and open files start ##################### +> # include /etc/nginx/nginx-snippets/cache-open-files.conf; +> # include /etc/nginx/nginx-snippets/cache-statics.conf; +> # include /etc/nginx/nginx-snippets/cache-js-css.conf; +> ##### Cache js css static content and open files stop ###################### +> ``` + +--- + +### Troubleshooting + +**Nginx fails to restart** +Run `nginx -t` and review any syntax errors reported in `/etc/nginx/conf.d/.conf`. + +**Access denied during database creation** +Your MariaDB setup likely does not use socket authentication. +Re-run the installer with the `-m` flag (and optionally `-a`) to provide credentials. +The installer will automatically re-detect your configuration. + +**PHP version mismatch** +The script automatically detects your installed PHP version, +but ensure that the PHP-FPM service (e.g., `php8.3-fpm`) is active. + +--- + +### FAQ + +**Q:** Why doesn’t the script ask for a MariaDB password by default? +**A:** Ubuntu 24.04’s MariaDB installation defaults to *socket authentication*, +allowing the local `root` user to connect without a password. +The installer detects this automatically and skips password prompts when applicable. + +**Q:** Can I run the installer multiple times? +**A:** Yes. Database and user creation use `IF NOT EXISTS`, making them safe to rerun. +Existing WordPress and Nginx configuration files are replaced, but no data is deleted. + +**Q:** Does this modify existing Nginx settings? +**A:** No. It adds a standalone host file in `/etc/nginx/conf.d/` +and validates configuration changes before applying them. + +--- + +### More Information + +More guides and documentation can be found on [wiki.x-files.dk](https://wiki.x-files.dk) + +--- + +### License + +Licensed under the [MIT License](./LICENSE). + +--- diff --git a/last-tested b/last-tested new file mode 100644 index 0000000..3f1f6ef --- /dev/null +++ b/last-tested @@ -0,0 +1,4 @@ +------------------------------------ +Last tested: 15-10-2025 (DD-MM-YYYY) +Environment: Ubuntu Server 24.04 LTS +------------------------------------ diff --git a/wordpressinstall b/wordpressinstall new file mode 100755 index 0000000..518cbf8 --- /dev/null +++ b/wordpressinstall @@ -0,0 +1,243 @@ +#!/usr/bin/env bash + +# Author : Allan Christensen +# First Created : 22052021 (DD-MM-YYYY) +# Description : Installs WordPress on Ubuntu 24.04 +# License : MIT License (see LICENSE file for details) + +# +# Are we root +# +if [[ $(id -u) -ne 0 ]]; then echo "" && echo "Must be root or use sudo" && echo "" ; exit 1 ; fi + +# +# Define variables and functions +# +phpver=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null || echo "8.3") ; phpfpm="php$phpver-fpm" + +# +# Function usage +# +usage () { + printf -- "\nwordpressinstall\n\n" + printf -- "%s\n\n" "$socket" + printf -- "Installs WordPress on Ubuntu\n\n" + printf -- "Usage:\n" + printf -- "sudo ./wordpressinstall -n -d -u -p [options]\n\n" + printf -- "Options:\n" + printf -- " -m Root or admin password $socketusage\n" + printf -- " -a Optional admin username $socketusage\n" + printf -- " -h | -help | --help Show this help screen\n\n" + printf -- "Examples:\n" + printf -- " sudo ./wordpressinstall -n wp.something.xyz -d wpdb -u wpuser -p wpPass123\n" + printf -- " sudo ./wordpressinstall -n wp.something.xyz -d wpdb -u wpuser -p wpPass123 -m rootpwd\n" + printf -- " sudo ./wordpressinstall -n wp.something.xyz -d wpdb -u wpuser -p wpPass123 -a admin -m adminpwd\n\n" +} + +# +# Function to check if a service is already running or not +# +serviceno () { printf "\n%s" "$service" ; printf " is not running cannot continue...\n\n"; } +servicedead () { status=$(systemctl is-active "$service"); if [[ "$status" != "active" ]]; then serviceno ; exit 1 ; fi; } + +# +# Function inputcheck +# +inputcheck () { + [[ -z "$hostname" ]] && { usage; echo ""; echo "Error! Hostname empty."; echo ""; exit 1; } + [[ -z "$dbname" ]] && { usage; echo ""; echo "Error! Database name empty."; echo ""; exit 1; } + [[ -z "$dbuser" ]] && { usage; echo ""; echo "Error! Database user empty."; echo ""; exit 1; } + [[ -z "$dbpass" ]] && { usage; echo ""; echo "Error! Database password empty."; echo ""; exit 1; } +} + +# +# If Nginx and MariaDB is not running then die +# +service="mariadb" ; servicedead ; service="nginx" ; servicedead + +# +# Check MariaDB authentication method (socket or not) +# +if mysql -u root -e ";" 2>/dev/null; then + socket="SOCKET DETECTED — no need for -a or -m" + socketusage="SOCKET DETECTED — this flag is not needed" + socketauth="yes" +else + socket="NO SOCKET DETECTED — you must use -a and -m" + socketusage="NO SOCKET DETECTED — this flag is required" + socketauth="no" +fi + +# +# Let's go +# +clear + +# +# Trap: show usage if user requests help. Recognizes -help and --help as early exits before getopts +# +if [[ "$1" == "-help" || "$1" == "--help" ]]; then usage ; exit 0 ; fi + +# +# Trap: malformed or missing input. Catches empty argument or argument not starting with '-' +# +if [[ $# -eq 0 || ! $1 =~ ^- ]]; then usage ; exit 1 ; fi + +# +# Configure command line options +# +while getopts ":n:d:u:p:m:a:h" option; do + case "$option" in + n) hostname=$(echo "$OPTARG" | tr '[:upper:]' '[:lower:]');; + d) dbname="$OPTARG";; + u) dbuser="$OPTARG";; + p) dbpass="$OPTARG";; + m) mariadbpwd="$OPTARG";; + a) mariadbadmin="$OPTARG";; + h) usage; exit 0;; + :) usage; echo ""; echo "Error! Option -$OPTARG requires an argument."; echo ""; exit 1;; + \?) usage; echo ""; echo "Error! Invalid option: -$OPTARG"; echo ""; exit 1;; + esac +done + +# +# Check if input conditions are met +# +inputcheck "$hostname" "$dbname" "$dbuser" "$dbpass" + +# +# Download, install, and configure the latest WordPress version +# +printf "\nDownloading latest WordPress package...\n" +mkdir -p /var/www/html +curl -sL https://wordpress.org/latest.tar.gz | tar -xzf - --transform "s,^wordpress,$hostname," -C "/var/www/html" || { echo "WordPress download or extraction failed"; exit 1; } +wptarget="/var/www/html/$hostname" +cp "$wptarget/wp-config-sample.php" "$wptarget/wp-config.php" +sed -i "s/database_name_here/$dbname/" "$wptarget/wp-config.php" +sed -i "s/username_here/$dbuser/" "$wptarget/wp-config.php" +sed -i "s/password_here/$dbpass/" "$wptarget/wp-config.php" +chown -R www-data: "$wptarget" + +# +# Clone nginx-snippets; if nginx-snippets exists then just pull latest changes +# +nginxsnippets="/etc/nginx/nginx-snippets" +repo="https://git.x-files.dk/webserver/nginx-snippets.git" +if [[ -d "$nginxsnippets/.git" ]]; then git -C "$nginxsnippets" pull --quiet; else git clone --quiet "$repo" "$nginxsnippets"; fi + +# +# Copy and adjust WordPress hardening config (runtime-only) +# +runtimeinc="/etc/nginx/conf.d/includes" ; mkdir -p "$runtimeinc" + +if [[ -f "$nginxsnippets/wp-hardening.conf" ]]; then + cp "$nginxsnippets/wp-hardening.conf" "$runtimeinc/wp-hardening.conf" + sed -i "s/phpVERSION/php$phpver/" "$runtimeinc/wp-hardening.conf" +else + echo "Warning: wp-hardening.conf not found in nginx-snippets" +fi + +# +# Copy WordPress rate-limit config (if missing) +# +if [[ -f "$nginxsnippets/wp-rate-limit.conf" ]]; then + cp --no-clobber "$nginxsnippets/wp-rate-limit.conf" /etc/nginx/conf.d/wp-rate-limit.conf 2>/dev/null +else + echo "Warning: wp-rate-limit.conf not found in nginx-snippets" +fi + +# +# Determine MariaDB login method (uses earlier socket variable) +# +mariadbadmin="${mariadbadmin:-root}" + +printf "\nChecking MariaDB access method...\n" + +if [[ "$socketauth" == "yes" ]]; then + dbmethod="socket" + printf "Socket authentication detected (root)\n" +elif [[ -n "$mariadbpwd" && -n "$mariadbadmin" ]]; then + dbmethod="admin" + printf "Using admin user authentication (%s)\n" "$mariadbadmin" +elif [[ -n "$mariadbpwd" ]]; then + dbmethod="password" + printf "Using root password authentication\n" +else + printf "\nERROR: No valid MariaDB authentication method found.\n" + printf "Tried socket, root password, and admin credentials.\n\n" + exit 1 +fi + +# +# Create WordPress database +# +case "$dbmethod" in + socket) + mysql -u root <