Before you start
This guide builds a classic LEMP stack (Linux, Nginx, MariaDB, PHP) and installs WordPress on it. You need a domain pointing at the server, a sudo account and a firewall that allows ports 80 and 443. If you would rather not run the server yourself, shared hosting on this site handles all of this for you.
Complete the database guide for MariaDB and the reverse proxy guide for Nginx and certificates. This guide only covers what is specific to PHP and WordPress. Replace example.com with your domain.
Install the packages on Ubuntu
Ubuntu 24.04 ships PHP 8.3. Install Nginx, PHP-FPM and the extensions WordPress commonly uses. The PHP-FPM socket is /run/php/php8.3-fpm.sock.
sudo apt update
sudo apt install nginx mariadb-server php-fpm php-mysql php-curl php-gd php-intl php-mbstring php-xml php-zip php-imagick certbot python3-certbot-nginx
sudo systemctl enable --now php8.3-fpm nginx mariadb
php --version
ls /run/php/Install the packages on AlmaLinux
AlmaLinux 9 provides PHP in its default repositories, and a newer version is available through module streams. PHP-FPM runs as the apache user by default. Change it to nginx so that Nginx and PHP agree on file ownership, and the socket path is /run/php-fpm/www.sock.
Use the maintained PHP 8.3 stream on a fresh AlmaLinux 9 installation. If the server already hosts PHP applications, review their compatibility before switching streams.
sudo dnf install epel-release policycoreutils-python-utils
sudo dnf module reset php
sudo dnf module enable php:8.3
sudo dnf install nginx mariadb-server php-fpm php-cli php-curl php-mysqlnd php-gd php-intl php-mbstring php-xml php-zip php-json certbot python3-certbot-nginx
sudo sed -i 's/^user = apache/user = nginx/;s/^group = apache/group = nginx/' /etc/php-fpm.d/www.conf
sudo sed -i 's/^;listen.owner = nobody/listen.owner = nginx/;s/^;listen.group = nobody/listen.group = nginx/' /etc/php-fpm.d/www.conf
sudo systemctl enable --now php-fpm nginx mariadb
sudo php-fpm -tt 2>&1 | tail -n 3Create the database
Use the MariaDB steps from the database guide to create a database and a user for WordPress, with a random password. Write the password down for the WordPress setup screen.
openssl rand -base64 24
sudo mysql <<'EOF'
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'PASTE_THE_GENERATED_PASSWORD';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EOFDownload and verify WordPress
Download the latest release from wordpress.org and compare it with the checksum published beside it before extracting. Put the files in /var/www/example.com and give them to the web server user. The user is www-data on Ubuntu and nginx on AlmaLinux.
cd /tmp
curl -fsSLO https://wordpress.org/latest.tar.gz
curl -fsSL https://wordpress.org/latest.tar.gz.sha1
sha1sum latest.tar.gzsudo mkdir -p /var/www/example.com
sudo tar -xzf /tmp/latest.tar.gz -C /var/www/example.com --strip-components=1
sudo chown -R www-data:www-data /var/www/example.comsudo mkdir -p /var/www/example.com
sudo tar -xzf /tmp/latest.tar.gz -C /var/www/example.com --strip-components=1
sudo chown -R nginx:nginx /var/www/example.com
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/example.com(/.*)?"
sudo restorecon -Rv /var/www/example.com
sudo setsebool -P httpd_can_network_connect_db 1Configure Nginx
This server block serves static files directly, sends PHP files to PHP-FPM and enables WordPress pretty permalinks. Ubuntu uses the socket /run/php/php8.3-fpm.sock and AlmaLinux uses /run/php-fpm/www.sock, so pick the right fastcgi_pass line.
Select the socket before testing Nginx: Ubuntu uses /run/php/php8.3-fpm.sock and AlmaLinux uses /run/php-fpm/www.sock.
sudo tee /etc/nginx/conf.d/example.com.conf >/dev/null <<'EOF'
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php;
client_max_body_size 64m;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock; # AlmaLinux: unix:/run/php-fpm/www.sock
}
location ~ /\.ht { deny all; }
location = /xmlrpc.php { deny all; }
}
EOF
# AlmaLinux only, before the test:
# sudo sed -i 's|unix:/run/php/php8.3-fpm.sock|unix:/run/php-fpm/www.sock|' /etc/nginx/conf.d/example.com.conf
sudo nginx -t && sudo systemctl reload nginxFinish setup and enable HTTPS
Visit http://example.com in your browser and follow the WordPress installer, entering the database name, user and password you created. Then obtain a certificate with Certbot as shown in the reverse proxy guide, and set both WordPress addresses to https in Settings, General.
sudo certbot --nginx -d example.com -d www.example.com
curl -I https://example.com/Secure and maintain it
Use a strong administrator password, keep WordPress, themes and plugins updated, and remove anything you do not use. The most common compromises come from outdated plugins. Back up the database and the wp-content folder on a schedule, and test a restore. Restrict file permissions so that PHP cannot overwrite core files if you are not using automatic updates.
sudo find /var/www/example.com -type d -exec chmod 755 {} +
sudo find /var/www/example.com -type f -exec chmod 644 {} +
sudo chmod 640 /var/www/example.com/wp-config.phpOfficial documentation
These upstream references provide more detail on the commands and workflows in this guide.