WORDPRESS

Installing WordPress on Ubuntu 24.04 LTS with Nginx, MariaDB, and PHP 8.3 (LEMP Stack)

02 Jun 2026 Administrator
Header Hero

Installing WordPress on Ubuntu 24.04 LTS with Nginx, MariaDB, and PHP 8.3 (LEMP Stack)



WordPress remains the premier open-source blogging engine and content management system (CMS) powering the modern web. Built using the PHP runtime language and structured over MySQL/MariaDB database management engines, WordPress provides a robust, user-friendly framework. It allows developers and content creators alike to rapidly deploy rich informational websites, personal blogs, or intricate web-based applications with an intuitive, streamlined administration control panel.



Infrastructure Prerequisites


Before initiating the terminal setup sequence, ensure that you have access to a Virtual Private Server (VPS) configured with root administrative privileges. This deployment guide focuses natively on an Ubuntu 24.04 LTS host machine; however, the architectural pipeline remains highly backwards-compatible with legacy systems such as Ubuntu 22.04 or 20.04. Additionally, verify that your active domain registry handles live DNS pointers mapping your domain strings straight to your instance's public IP address.



High-Level Implementation Outline


The system compilation workflow for this web cluster relies on the following core phases:



  1. Refreshing baseline operational dependencies and localizing system time management.

  2. Compiling and initializing the high-performance Nginx reverse-proxy web server layer.

  3. Deploying the MariaDB transactional database infrastructure.

  4. Linking validated custom PPA software tracks to build the PHP 8.3 interpreter along with its foundational engine modules.

  5. Fetching, unpacking, and hardening directory file ownership lines for the canonical WordPress core master sources.

  6. Structuring isolated relational tables, system database users, and credential mappings.

  7. Assembling a secure, high-performance Nginx virtual host server block manifest.

  8. Enforcing transit network encryptions using automated Let's Encrypt TLS/SSL configuration keys.






Step 1: Refreshing Repositories and Setting System Timezones


As a key operations baseline, run a full update against your server's package manager indexes to fetch the newest system upgrades and core environment patches:



sudo apt update && sudo apt upgrade -y


Adjust your local host server daemon clock properties to mirror your physical region. This step ensures that operational system logs, internal transaction metrics, and automation crontab execution lines align precisely with your local clock (e.g., configuring to Asia/Jakarta):



sudo timedatectl set-timezone Asia/Jakarta





Step 2: Deploying the Nginx Web Server Engine


To establish a stable web routing environment, initialize the high-performance Nginx web server engine on your host machine:



sudo apt install -y nginx


Launch the web server process daemon and register it to boot seamlessly alongside the core operating system upon a hardware reboot cycle:



sudo systemctl start nginx
sudo systemctl enable nginx


Validate basic connectivity by pointing any local web browser directly to the public network IP address assigned to your server. The default Nginx landing screen confirmation notice should render smoothly.





If the connection handshake fails or times out, your host firewall matrices are likely blockading incoming requests. Override this constraint by inserting explicit access rules within your iptables tables ruleset to accept traffic on ports 80 and 443:



sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT


Reload your browser window to verify that the Nginx default index wrapper loads securely on the host network.






Step 3: Compiling the MariaDB Relational Database Cluster


To handle the structured backend relational tables for WordPress, deploy the MariaDB database software utilities onto your system node:



sudo apt install -y mariadb-server mariadb-client


Following a successful build, boot the core execution service, register the system daemon for automated initialization on startup, and check its system log outputs to confirm proper functionality:



sudo service mariadb start
sudo systemctl enable mariadb
sudo service mariadb status


Ensure that the active daemon returns a secure and functioning runtime response block.








Step 4: Provisioning the PHP 8.3 Language Runtime Environment


This deployment leverages the modern PHP 8.3 interpreter pipeline, accompanied by several extension utilities required by WordPress to process application data smoothly.



Begin by deploying the foundational validation certificates and repository management tooling onto the host architecture:



sudo apt update
sudo apt install -y lsb-release gnupg2 ca-certificates apt-transport-https software-properties-common


Inject the highly optimized and verified Ondrej PHP APT tracking archive list into your local system core repository tracks:



sudo add-apt-repository ppa:ondrej/php
sudo apt update


Deploy the main PHP 8.3 interpreter along with its FPM process manager module and the specific structural extensions needed to run WordPress:



sudo apt install -y php8.3 php8.3-fpm php8.3-bcmath php8.3-xml php8.3-mysql php8.3-zip php8.3-intl php8.3-ldap php8.3-gd php8.3-cli php8.3-bz2 php8.3-curl php8.3-mbstring php8.3-imagick php8.3-tokenizer php8.3-opcache php8.3-redis php8.3-cgi





Step 5: Pulling and Extracting the WordPress Source Code Archive


We will compile the application stack using official archive components from the source distribution paths to maintain full visibility over the codebase.



Install the standard wget download utility and download the newest compressed release archive from the official distribution hub:



sudo apt install wget
cd ~
wget http://wordpress.org/latest.tar.gz


Unpack the downloaded tarball to expose the nested application files:



sudo tar -xzvf latest.tar.gz


Move the extracted directory structure directly into your web document root folder path location:



sudo mv wordpress /var/www/wordpress


Duplicate the baseline initialization parameters blueprint file to construct an active wp-config.php file. This configuration document maps backend variables and relational engine access credentials:



sudo cp /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php


Enforce strong system-level file ownership rules, assigning runtime access permissions exclusively to the web server process user identifier account (www-data):



sudo chown -R www-data:www-data /var/www/wordpress/
sudo chmod -R 755 /var/www/wordpress/





Step 6: Provisioning the Relational Core Application Database


Log in to the MariaDB command terminal environment using root access privileges to map out your database tables and isolate access scopes:



sudo mariadb


Generate a separate, dedicated database store container for your application:



CREATE DATABASE wordpress_db;


Create an isolated, non-root system user profile assigned to a highly secure custom authentication passphrase entry:



CREATE USER wordpressuser@localhost IDENTIFIED BY 'your-password';


Grant all necessary administrative permissions and operational privileges over your data tables exclusively to this system profile account:



GRANT ALL PRIVILEGES ON wordpress_db.* TO wordpressuser@localhost IDENTIFIED BY 'your-password';


Commit these changes across the relational management layers immediately and exit the terminal command console:



FLUSH PRIVILEGES;
EXIT;


Your database preparation parameters sequence should resemble the terminal execution block shown below.








Step 7: Engineering the Nginx Virtual Host Infrastructure


An Nginx Virtual Host configuration profile explicitly delegates domain pointers, handles security controls, balances traffic loads, and hands file execution streams off to the PHP-FPM processor socket.



Create a dedicated configuration block file within your web server sites repository directory utilizing a terminal text editor:



sudo nano /etc/nginx/sites-available/wordpress.conf


Inject the following optimized and hardened structural routing parameters into the document. Remember to replace all instances of namadomain.com with your live production domain name:



server {
listen 80;
server_name namadomain.com www.namadomain.com;
root /var/www/wordpress;
index index.php;
autoindex off;

# Access log
access_log /var/log/nginx/namadomain-access.log combined;
# Error log
error_log /var/log/nginx/namadomain-error.log;

# Additional Configuration
client_max_body_size 10M;
client_body_buffer_size 128k;
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5;

location / {
try_files $uri $uri/ /index.php?$args;
}

# Block PHP Direct Access to Upload and Includes Directory
location ~* /(?:wp-content/uploads|wp-includes)/.*\.php$ {
deny all;
}

# Block Access to xmlrpc
location = /xmlrpc.php {
deny all;
}

location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
}

location = /favicon.ico {
log_not_found off;
access_log off;
expires max;
}

location = /robots.txt {
log_not_found off;
access_log off;
}

# Disable Access to Hidden Files
location ~ /\. {
deny all;
}

# Disable Execute PHP File on Upload Directory
location /wp-content/uploads/ {
location ~ \.php$ {
deny all;
}
}

# Header Security
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Frame-Options "SAMEORIGIN";

# Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_comp_level 5;
gzip_types application/json text/css application/x-javascript application/javascript image/svg+xml;
gzip_proxied any;

# Cache-Control
location ~* \.(jpg|jpeg|gif|png|webp|svg|woff|woff2|ttf|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 360d;
}

# Rest API
location ~ ^/wp-json/ {
rewrite ^/wp-json/(.*?)$ /?rest_route=/$1 last;
}
}


Link the finished virtual configuration file into the active Nginx site execution directories to prepare for system tracking:



sudo ln -s /etc/nginx/sites-available/wordpress.conf /etc/nginx/sites-enabled/


Run a verification trace to confirm that your newly added rules do not contain structural typos or syntax anomalies:



sudo nginx -t


Verify that your terminal window returns a success verification confirmation status log.





Reload your Nginx service parameters to safely push the changes live across active worker nodes:



sudo systemctl reload nginx





Step 8: Mapping Domain DNS Records


To connect your server to a friendly public domain string instead of a row of raw numbers, access your central domain registry workspace or DNS provider. If you use Cloudflare edge proxy networks, set up an A Record entry pointing your root domain parameters straight to your production VPS public IP network address.





Keep in mind that global networks can take a few minutes up to several hours to fully update across internet routing points. Edge cloud handlers typically speed up this file propagation curve to just 1 or 2 minutes.






Step 9: Provisioning Let's Encrypt TLS/SSL Transport Security


To secure user traffic and ensure compliance with modern encryption standards, establish verified HTTPS configurations. Install the standard Certbot core library automation package alongside its dedicated Nginx connector utilities:



sudo apt install -y certbot python3-certbot-nginx


Execute the interactive validation routine to query the keys, map secure redirects, and deploy transport layer encryption automatically. Be sure to update the email parameters and targeted web address values with your live data:



sudo certbot --nginx --agree-tos --redirect --email admin@yourdomain.com -d yourdomain.com,www.yourdomain.com


Once Certbot confirms deployment, your web framework will run entirely over secure HTTPS channels. Open your domain name in any browser to complete the WordPress graphical installation script and database setup wizard safely.