initial commit

This commit is contained in:
2025-10-23 15:46:59 +02:00
commit 1e94746f13
4 changed files with 442 additions and 0 deletions

21
LICENSE Normal file
View File

@@ -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.

174
README.md Normal file
View File

@@ -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 dont 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 <domain> -d <dbname> -u <dbuser> -p <dbpass> [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 <password>` | MariaDB root or admin password — *required only if socket authentication is disabled* |
| `-a <username>` | 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://<domain>/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/<domain>` | WordPress site directory |
| `/etc/nginx/conf.d/<domain>.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/<domain>.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 doesnt the script ask for a MariaDB password by default?
**A:** Ubuntu 24.04s 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).
---

4
last-tested Normal file
View File

@@ -0,0 +1,4 @@
------------------------------------
Last tested: 15-10-2025 (DD-MM-YYYY)
Environment: Ubuntu Server 24.04 LTS
------------------------------------

243
wordpressinstall Executable file
View File

@@ -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 <domain> -d <dbname> -u <dbuser> -p <dbpass> [options]\n\n"
printf -- "Options:\n"
printf -- " -m <mariadb admin password> Root or admin password $socketusage\n"
printf -- " -a <mariadb admin user> 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 <<EOF
CREATE DATABASE IF NOT EXISTS $dbname;
CREATE USER IF NOT EXISTS '$dbuser'@'localhost' IDENTIFIED BY '${dbpass//\'/\'\\\'\'}';
GRANT ALL PRIVILEGES ON $dbname.* TO '$dbuser'@'localhost';
FLUSH PRIVILEGES;
EOF
;;
password)
mysql -u root -p"${mariadbpwd}" <<EOF
CREATE DATABASE IF NOT EXISTS $dbname;
CREATE USER IF NOT EXISTS '$dbuser'@'localhost' IDENTIFIED BY '${dbpass//\'/\'\\\'\'}';
GRANT ALL PRIVILEGES ON $dbname.* TO '$dbuser'@'localhost';
FLUSH PRIVILEGES;
EOF
;;
admin)
mysql -u "${mariadbadmin}" -p"${mariadbpwd}" <<EOF
CREATE DATABASE IF NOT EXISTS $dbname;
CREATE USER IF NOT EXISTS '$dbuser'@'localhost' IDENTIFIED BY '${dbpass//\'/\'\\\'\'}';
GRANT ALL PRIVILEGES ON $dbname.* TO '$dbuser'@'localhost';
FLUSH PRIVILEGES;
EOF
;;
esac
#
# Create WordPress Nginx configuration
#
cp "$nginxsnippets/hostfiles/wordpress.80.conf" /etc/nginx/conf.d/"$hostname".conf
sed -i "s/DOMAIN/$hostname/g" /etc/nginx/conf.d/"$hostname".conf
sed -i "s/VERSION/$phpver/" /etc/nginx/conf.d/"$hostname".conf
sed -i "s|/etc/nginx/conf.d/wp-hardening.conf|$runtimeinc/wp-hardening.conf|" /etc/nginx/conf.d/"$hostname".conf
#
# Validate Nginx configuration before restarting
#
nginx -t || { echo "" ; echo "Nginx configuration test failed. Please check /etc/nginx/conf.d/ for errors." ; echo "" ; exit 1; }
#
# Restart Nginx and PHP-FPM for changes to take effect
#
systemctl restart "$phpfpm" && systemctl restart nginx
#
# Wordpress notice
#
wpnotice=$(cat <<EOF
-----------------------------------------------------------------------------------
IMPORTANT:
Go to http://$hostname/wp-admin/install.php and complete the setup
-----------------------------------------------------------------------------------
EOF
)
#
# Print notice
#
printf '%s\n' "$wpnotice"
#
# All done
#
printf "\nAll Done — WordPress files located at: %s\n" "$wptarget"
#
# End of script
#