You've already forked wordpress-ubuntu
latest commit
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal 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.
|
||||
163
README.md
Normal file
163
README.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# WordPress for Ubuntu 24.04
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](./LICENSE)
|
||||
|
||||
Install WordPress on Ubuntu 24.04 server.
|
||||
|
||||
This is not a demo and not an experiment.
|
||||
A production-focused installer — correct permissions, prepared DB, no web-based setup guessing.
|
||||
|
||||
## Why this installer exists
|
||||
Most WordPress guides leave insecure permissions, unclear DB setup and missing caching. This avoids all three.
|
||||
|
||||
## What this installer does
|
||||
✔ Downloads the latest WordPress release
|
||||
✔ Creates database + user automatically
|
||||
✔ Generates validated Nginx host config
|
||||
✔ Socket or password authentication supported
|
||||
✔ Safe to re-run without data loss
|
||||
|
||||
## What this installer does *NOT* do
|
||||
It won’t stop you from running the script without reading the documentation like there’s no tomorrow.
|
||||
Skip the README, and whatever happens next is your headache, not a bug report.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This script expects:
|
||||
|
||||
✔ Nginx installed
|
||||
✔ PHP-FPM installed
|
||||
✔ MariaDB/MySQL running *(socket or password mode supported)*
|
||||
|
||||
### Optional Installers (if you need them — saves you some googling)
|
||||
|
||||
- [Install Nginx + PHP-FPM on Ubuntu](https://git.x-files.dk/webserver/nginx-ubuntu)
|
||||
- [Install MariaDB on Ubuntu](https://git.x-files.dk/database/mariadb-ubuntu)
|
||||
- [Install MySQL on Ubuntu](https://git.x-files.dk/database/mysql-ubuntu)
|
||||
|
||||
---
|
||||
|
||||
## 1. Download
|
||||
|
||||
```
|
||||
git clone https://git.x-files.dk/webapps/wordpress-ubuntu.git
|
||||
```
|
||||
|
||||
```
|
||||
cd wordpress-ubuntu
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Install WordPress
|
||||
|
||||
```
|
||||
sudo ./wordpressinstall -n <domain> -d <dbname> -u <dbuser> -p <dbpass> [options]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
Socket authentication detected → simple command:
|
||||
|
||||
```
|
||||
sudo ./wordpressinstall -n wp.example.com -d wpdb -u wpuser -p wpPass123
|
||||
```
|
||||
|
||||
Socket unavailable → add database credentials manually:
|
||||
|
||||
```
|
||||
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 | Meaning |
|
||||
|---|---|
|
||||
| `-m <password>` | MariaDB/MySQL admin or root password *(only if socket OFF)* |
|
||||
| `-a <username>` | DB admin username (defaults to `root`) |
|
||||
| `-h` / `--help` | Show help |
|
||||
|
||||
---
|
||||
|
||||
## What this installer does
|
||||
|
||||
✔ Downloads + configures latest WordPress
|
||||
✔ Creates DB + DB-user if they don’t exist
|
||||
✔ Generates Nginx host file automatically
|
||||
✔ Detects socket vs password auth
|
||||
✔ Validates Nginx (`nginx -t`) before reload
|
||||
✔ Supports safe re-runs
|
||||
✔ Built for production, not testing
|
||||
|
||||
---
|
||||
|
||||
## After installation
|
||||
|
||||
Visit:
|
||||
|
||||
```
|
||||
http://<domain>/wp-admin/install.php
|
||||
```
|
||||
|
||||
Complete the setup wizard — database already wired.
|
||||
|
||||
---
|
||||
|
||||
## File & Config Layout
|
||||
|
||||
| Path | Purpose |
|
||||
|---|---|
|
||||
| `/var/www/html/<domain>` | WordPress directory |
|
||||
| `/etc/nginx/conf.d/<domain>.conf` | Virtualhost config |
|
||||
| `/etc/nginx/conf.d/includes/wp-hardening.conf` | Security |
|
||||
| `/etc/nginx/conf.d/wp-rate-limit.conf` | Rate limit |
|
||||
|
||||
---
|
||||
|
||||
## HTTPS Support (443)
|
||||
|
||||
Enable TLS using:
|
||||
|
||||
https://git.x-files.dk/webserver/nginx-snippets/src/branch/main/hostfiles/wordpress.443.conf
|
||||
|
||||
Caching snippets (disabled until uncommented):
|
||||
|
||||
```
|
||||
# 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;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Cause | Fix |
|
||||
|---|---|---|
|
||||
| Nginx restart fails | Config error | `nginx -t` |
|
||||
| DB denied | No socket auth | Use `-m` |
|
||||
| PHP errors | Wrong FPM version | Check `php8.3-fpm` |
|
||||
|
||||
---
|
||||
|
||||
### 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).
|
||||
|
||||
---
|
||||
6
last-tested
Normal file
6
last-tested
Normal file
@@ -0,0 +1,6 @@
|
||||
------------------------------------
|
||||
Last tested: 19-12-2025 (DD-MM-YYYY)
|
||||
Environment: Ubuntu Server 24.04 LTS
|
||||
Database : MariaDB 10.11.13
|
||||
Database : MySQL 8.0.44-0
|
||||
------------------------------------
|
||||
307
wordpressinstall
Executable file
307
wordpressinstall
Executable file
@@ -0,0 +1,307 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Author : Allan Christensen
|
||||
# First Created : 22-05-2021 (DD-MM-YYYY)
|
||||
# Description : Installs WordPress on Ubuntu 24.04 (MariaDB or MySQL)
|
||||
# License : MIT License
|
||||
|
||||
#
|
||||
# Are we root
|
||||
#
|
||||
if [[ $(id -u) -ne 0 ]]; then echo "" && echo "Must be root or use sudo" && echo "" ; exit ; fi
|
||||
|
||||
#
|
||||
# Detect PHP-FPM version
|
||||
#
|
||||
phpfpm=$(systemctl list-unit-files --type=service | awk '/php[0-9]+\.[0-9]+-fpm\.service/ {sub(".service","",$1); print $1; exit}')
|
||||
if [[ -z "$phpfpm" ]]; then printf "\nUnable to detect PHP-FPM version. Is PHP-FPM installed?\n\n" ; exit 1 ; fi
|
||||
|
||||
#
|
||||
# Detect database engine (MariaDB or MySQL)
|
||||
#
|
||||
if systemctl list-unit-files | grep -q '^mariadb\.service'; then
|
||||
db_engine="mariadb"
|
||||
db_service="mariadb"
|
||||
elif systemctl list-unit-files | grep -q '^mysql\.service'; then
|
||||
db_engine="mysql"
|
||||
db_service="mysql"
|
||||
else
|
||||
printf "\nNo supported database server found.\n\n"
|
||||
printf "You must have MariaDB or MySQL installed and enabled.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Check if required services are running
|
||||
#
|
||||
for svc in nginx "$db_service" "$phpfpm"; do
|
||||
systemctl is-active --quiet "$svc" || {
|
||||
printf "\n%s is not running, cannot continue...\n\n" "${svc^}"
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
#
|
||||
# Check DB authentication method
|
||||
# (local root access via socket / auth_socket / passwordless)
|
||||
#
|
||||
if mysql -u root -e ";" 2>/dev/null; then
|
||||
socketauth="yes"
|
||||
else
|
||||
socketauth="no"
|
||||
fi
|
||||
|
||||
#
|
||||
# Usage
|
||||
#
|
||||
usage() {
|
||||
printf -- "\nwordpressinstall (Ubuntu 24.04)\n\n"
|
||||
printf -- "Database engine detected: %s\n\n" "$db_engine"
|
||||
|
||||
if [[ "$socketauth" == "yes" ]]; then
|
||||
printf -- "LOCAL ROOT ACCESS DETECTED — no need for -a or -m\n\n"
|
||||
printf -- "Usage:\n"
|
||||
printf -- " sudo ./wordpressinstall -n <domain> -d <wpdbname> -u <wpdbuser> -p <wpdbpass>\n\n"
|
||||
printf -- "Example:\n"
|
||||
printf -- " sudo ./wordpressinstall -n wp.example.com -d wpdb -u wpuser -p wpPass123\n\n"
|
||||
else
|
||||
printf -- "NO LOCAL ROOT ACCESS — you must use -a and -m\n\n"
|
||||
printf -- "Usage:\n"
|
||||
printf -- " sudo ./wordpressinstall -n <domain> -d <wpdbname> -u <wpdbuser> -p <wpdbpass> -a <db-admin-user> -m <db-admin-password>\n\n"
|
||||
printf -- "Examples:\n"
|
||||
printf -- " sudo ./wordpressinstall -n wp.example.com -d wpdb -u wpuser -p wpPass123 -a root -m RootDBPassword\n"
|
||||
printf -- " sudo ./wordpressinstall -n wp.example.com -d wpdb -u wpuser -p wpPass123 -a admin -m AdminDBPassword\n\n"
|
||||
fi
|
||||
|
||||
printf -- "Options:\n"
|
||||
printf -- " -h | -help | --help Show this help screen\n\n"
|
||||
}
|
||||
|
||||
#
|
||||
# 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:a:m:h" option; do
|
||||
case "$option" in
|
||||
n) hostname=$(echo "$OPTARG" | tr '[:upper:]' '[:lower:]');;
|
||||
d) dbname="$OPTARG";;
|
||||
u) dbuser="$OPTARG";;
|
||||
p) dbpass="$OPTARG";;
|
||||
a) db_admin_user="$OPTARG";;
|
||||
m) db_admin_pwd="$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
|
||||
|
||||
#
|
||||
# Parse and validate input
|
||||
#
|
||||
if [[ -z "$hostname" || -z "$dbname" || -z "$dbuser" || -z "$dbpass" ]]; then
|
||||
usage
|
||||
printf "\nERROR: Missing required arguments.\n"
|
||||
printf "Hostname (-n), Database name (-d), User (-u), and Password (-p) are required.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Normalise DB admin defaults
|
||||
#
|
||||
db_admin_user="${db_admin_user:-root}"
|
||||
|
||||
#
|
||||
# Validate domain format (RFC-ish, same family as your other installers)
|
||||
#
|
||||
if [[ "$hostname" =~ ^- ]]; then
|
||||
printf "\nERROR: Domain cannot start with a hyphen.\n"
|
||||
printf "Example of valid input: wp.example.com\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$hostname" =~ [[:space:]/_] ]]; then
|
||||
printf "\nERROR: Domain cannot contain spaces, slashes, or underscores.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$hostname" =~ ^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$ ]]; then
|
||||
printf "\nERROR: Invalid domain format.\n"
|
||||
printf "Example of valid input: wp.example.com\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Validate DB identifiers (keep it simple and safe)
|
||||
#
|
||||
if [[ "$dbname" =~ [^a-zA-Z0-9_] ]]; then
|
||||
printf "\nERROR: Database name must only contain letters, numbers, and underscores.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$dbuser" =~ [^a-zA-Z0-9_] ]]; then
|
||||
printf "\nERROR: Database user must only contain letters, numbers, and underscores.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$dbname" =~ [[:space:]] || "$dbuser" =~ [[:space:]] || "$dbpass" =~ [[:space:]] ]]; then
|
||||
printf "\nERROR: Database name, user, and password cannot contain whitespace.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# If no socket auth, require admin credentials
|
||||
#
|
||||
if [[ "$socketauth" == "no" ]]; then
|
||||
if [[ -z "${db_admin_pwd:-}" ]]; then
|
||||
usage
|
||||
printf "\nERROR: No local root access detected — you must provide -a and -m.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Ensure curl and git are installed
|
||||
#
|
||||
for tool in curl git; do dpkg -s "$tool" &>/dev/null || apt install -y -qq "$tool" ; done
|
||||
|
||||
#
|
||||
# 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"
|
||||
|
||||
#
|
||||
# Adjust WordPress DB_HOST depending on DB auth type
|
||||
# - socket/auth_socket prefers localhost (socket)
|
||||
# - password/admin prefers 127.0.0.1 (TCP)
|
||||
#
|
||||
if [[ "$socketauth" == "no" ]]; then
|
||||
sed -i "s/^define( 'DB_HOST'.*/define( 'DB_HOST', '127.0.0.1' );/" "$wptarget/wp-config.php"
|
||||
fi
|
||||
|
||||
#
|
||||
# Set permissions on WordPress directory
|
||||
#
|
||||
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
|
||||
|
||||
#
|
||||
# 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/PHPVERSION/$phpfpm/" /etc/nginx/conf.d/"$hostname".conf
|
||||
|
||||
#
|
||||
# WordPress hardening
|
||||
#
|
||||
mkdir -p /etc/nginx/includes
|
||||
cp "$nginxsnippets/wp-hardening.conf" /etc/nginx/includes/wp-hardening.conf
|
||||
sed -i "s/PHPVERSION/$phpfpm/" /etc/nginx/includes/wp-hardening.conf
|
||||
cp --no-clobber "$nginxsnippets/wp-rate-limit.conf" /etc/nginx/conf.d/wp-rate-limit.conf 2>/dev/null
|
||||
|
||||
#
|
||||
# Determine DB login method (uses earlier socketauth variable)
|
||||
#
|
||||
printf "\nChecking database access method...\n"
|
||||
|
||||
if [[ "$socketauth" == "yes" ]]; then
|
||||
dbmethod="socket"
|
||||
printf "Socket authentication detected (root)\n"
|
||||
else
|
||||
dbmethod="admin"
|
||||
printf "Using admin user authentication (%s)\n" "$db_admin_user"
|
||||
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
|
||||
;;
|
||||
admin)
|
||||
mysql -u "${db_admin_user}" -p"${db_admin_pwd}" <<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
|
||||
|
||||
#
|
||||
# Restarting Nginx and PHP-FPM for changes to take effect
|
||||
#
|
||||
printf "\nRestarting services...\n"
|
||||
systemctl restart "$phpfpm"
|
||||
systemctl restart nginx
|
||||
|
||||
#
|
||||
# WordPress notice
|
||||
#
|
||||
wpdbhost="localhost"
|
||||
[[ "$socketauth" == "no" ]] && wpdbhost="127.0.0.1"
|
||||
|
||||
wpnotice=$(cat <<EOF
|
||||
-----------------------------------------------------------------------------------
|
||||
NEXT STEP:
|
||||
|
||||
Go to http://$hostname/wp-admin/install.php and complete the WordPress setup
|
||||
|
||||
Database summary (wp-config.php):
|
||||
|
||||
Database Host : $wpdbhost
|
||||
Database Name : $dbname
|
||||
Database User : $dbuser
|
||||
Database Pass : $dbpass
|
||||
-----------------------------------------------------------------------------------
|
||||
EOF
|
||||
)
|
||||
|
||||
#
|
||||
# Print notice
|
||||
#
|
||||
printf '%s\n' "$wpnotice"
|
||||
|
||||
#
|
||||
# All done
|
||||
#
|
||||
printf "\nAll Done...\n"
|
||||
|
||||
#
|
||||
# End of script
|
||||
#
|
||||
Reference in New Issue
Block a user