Nginx is usually the better fit when you want WordPress on Ubuntu without the extra Apache layer, especially on a VPS where memory use and straightforward request handling matter. That makes it practical to install WordPress on Ubuntu with Nginx, MariaDB, and PHP-FPM while keeping the stack lean and easy to tune.
Ubuntu 26.04, 24.04, and 22.04 stay in scope here, and the main release-specific differences are the default package branches and PHP-FPM service names. The setup runs from the LEMP stack through the WordPress installer, HTTPS, upload-limit tuning, and a few common redirect and session fixes.
Prepare the LEMP Stack for WordPress on Ubuntu
The package names stay consistent across Ubuntu 26.04, 24.04, and 22.04, but the default branches do not. The PHP-FPM service name and socket path are the main release-specific details you need to reuse later in the Nginx server block.
| Ubuntu release | Nginx | MariaDB | PHP-FPM service |
|---|---|---|---|
| 26.04 LTS | 1.28.x | 11.8.x | php8.5-fpm |
| 24.04 LTS | 1.24.x | 10.11.x | php8.3-fpm |
| 22.04 LTS | 1.18.x | 10.6.x | php8.1-fpm |
Update Ubuntu Before WordPress Installation
Refresh the package index and install any pending updates before you start the stack setup. That keeps the package metadata current and reduces the chance of avoidable dependency conflicts.
sudo apt update && sudo apt upgrade
These commands use
sudofor tasks that need root privileges. If your user is not in the sudoers file yet, follow the guide on how to add a new user to sudoers on Ubuntu before continuing.
Install Initial Packages for WordPress on Ubuntu
Install the small helper packages used later for downloading and extracting the WordPress archive.
sudo apt install curl wget unzip -y
Install Nginx on Ubuntu – LEMP Stack Part 1
Start with Ubuntu’s default Nginx package. If you still need the wider Nginx-specific walkthrough, install Nginx on Ubuntu first.
sudo apt install nginx -y
Ubuntu enables and starts nginx.service during installation, so the next check is usually enough to confirm the web server is ready.
systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running)
Install Nginx Mainline on Ubuntu (Optional)
If you want newer HTTP, TLS, or reverse-proxy features than the Ubuntu package provides, install Nginx Mainline on Ubuntu instead. The default package is still fine for a standard WordPress deployment.
Configure UFW Firewall for Nginx and WordPress
If this server does not already use UFW, set it up before you expose WordPress over HTTP or HTTPS. The broader guide to install and configure UFW firewall on Ubuntu covers extra rules and logging, while the steps here focus on the Nginx profiles WordPress needs.
First, ensure UFW is installed on your Ubuntu system:
sudo apt install ufw -y
After installation, enable UFW on your system. By default, UFW will deny all incoming and allow all outgoing connections. To enable the firewall, use the following command:
sudo ufw enable
List the available UFW application profiles so you can pick the Nginx rule that matches your exposure level:
sudo ufw app list
Available applications: Nginx Full Nginx HTTP Nginx Secure OpenSSH
The output shows that Nginx HTTP runs on port 80, Nginx Secure runs on port 443 (HTTPS), and Nginx Full combines both. To enable both HTTP and HTTPS access, use the Nginx Full profile:
sudo ufw allow 'Nginx Full'
However, depending on your specific needs, you may want to adjust the profile. For example, if you only require HTTPS access, use the Nginx Secure profile:
sudo ufw allow 'Nginx Secure'
Or, if you only require HTTP access, use the Nginx HTTP profile:
sudo ufw allow 'Nginx HTTP'
Install MariaDB on Ubuntu – LEMP Stack Part 2
MariaDB is the database layer for this stack, and Ubuntu’s default packages are enough for a normal WordPress site. If you need a newer upstream branch or a separate repository path, install MariaDB on Ubuntu with the versioned guide instead.
Install the server and client packages together so you can create the WordPress database locally from the same machine.
sudo apt install mariadb-server mariadb-client -y
Ubuntu also enables and starts mariadb.service during installation, so verify the service before you move on.
systemctl status mariadb
● mariadb.service - MariaDB 11.8.6 database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: enabled)
Active: active (running)
On Ubuntu 26.04, the status line reflects MariaDB 11.8.x. Ubuntu 24.04 and 22.04 use the same service name with the older 10.11.x and 10.6.x branches.
Secure MariaDB on Ubuntu with the Security Script
Run MariaDB’s hardening helper before you create the WordPress database. It lets you remove the anonymous accounts, lock down remote root access, and delete the default test database in one pass.
Start the hardening script with:
sudo mariadb-secure-installation
Answer the prompts to set a root password, remove anonymous accounts, block remote root logins, and delete the test database.
MariaDB Security Script Prompts
The script presents several security prompts. Answer Y to each prompt to enable all security features:
Enter current password for root (enter for none): OK, successfully used password, moving on... Switch to unix_socket authentication [Y/n] Y Enabled successfully! Change the root password? [Y/n] Y New password: Re-enter new password: Password updated successfully! Remove anonymous users? [Y/n] Y ... Success! Disallow root login remotely? [Y/n] Y ... Success! Remove test database and access to it? [Y/n] Y ... Success! Reload privilege tables now? [Y/n] Y ... Success! All done! Your MariaDB installation should now be secure.
Install PHP on Ubuntu – LEMP Stack Part 3
Install the PHP-FPM, CLI, and extension packages WordPress actually uses instead of the broad php metapackage. On Ubuntu 24.04 and 22.04, that metapackage can drag Apache helpers into the stack, which is the last thing you want on an Nginx deployment. If you still need the wider package breakdown, install PHP on Ubuntu from the dedicated guide.
Install PHP-FPM with the common WordPress extensions in one step:
sudo apt install php-cli php-fpm php-mbstring php-bcmath php-xml php-mysql php-gd php-curl php-zip php-imagick php-intl -y
Ubuntu names the PHP-FPM service after the installed branch, so match the service name to your release:
- Ubuntu 22.04:
php8.1-fpm - Ubuntu 24.04:
php8.3-fpm - Ubuntu 26.04:
php8.5-fpm
Check the active PHP branch first, then verify the matching PHP-FPM service.
php -v | head -1
PHP 8.5.2 (cli) (built: Jan 21 2026 17:35:28) (NTS)
Ubuntu 24.04 reports PHP 8.3.x here, and Ubuntu 22.04 reports PHP 8.1.x. Use the matching service name from the list above for the status check:
systemctl status php8.5-fpm --no-pager
● php8.5-fpm.service - The PHP 8.5 FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php8.5-fpm.service; enabled; preset: enabled)
Active: active (running) since ...
Invocation: c3caa6eff53f4b7780326a120b6ba883
Install the WordPress Backend on Ubuntu
With Nginx, MariaDB, and PHP-FPM ready, finish the local WordPress setup by unpacking the files, creating a database, and writing the WordPress configuration file.
Create the WordPress Directory Structure on Ubuntu
WordPress publishes a direct latest.zip archive on WordPress.org. Download it locally, then extract it into /var/www/html/.
wget https://wordpress.org/latest.zip
Extract the archive into the web root directory:
sudo unzip latest.zip -d /var/www/html/
Give the extracted files to the web server user so Nginx and PHP-FPM can read them and WordPress can manage uploads later.
sudo chown -R www-data:www-data /var/www/html/wordpress/
Then normalize the directory and file modes. WordPress does not need world-writable permissions for a standard Nginx deployment.
Use 755 for directories and 644 for files:
sudo find /var/www/html/wordpress -type d -exec chmod 755 {} \;
sudo find /var/www/html/wordpress -type f -exec chmod 644 {} \;
That leaves www-data as the owner, while 755 keeps directories searchable and 644 keeps regular files readable without making them writable for every user on the server.
Create a Database for WordPress on Ubuntu
Create a dedicated database and user instead of reusing the MariaDB root account. That keeps WordPress limited to the one database it actually needs.
sudo mariadb -u root
Run the following SQL inside the MariaDB shell. Replace the example password before you paste it.
CREATE DATABASE wordpressdb;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'change-this-password';
GRANT ALL PRIVILEGES ON wordpressdb.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
If you prefer a browser-based database tool later, you can also install phpMyAdmin with the LEMP stack on Ubuntu.
Configure WordPress Files on Ubuntu
Next, turn the sample configuration into the live wp-config.php file and add the database credentials you just created.
cd /var/www/html/wordpress/
Copy the sample file and keep the original as a fallback.
sudo cp wp-config-sample.php wp-config.php
Open the new configuration file in your preferred editor:
sudo nano wp-config.php
Update the database name, username, and password fields. Leave DB_HOST as localhost unless your MariaDB server runs on another host.
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpressdb' ); <--------------- change this
/* MySQL database username */
define( 'DB_USER', 'wpuser' ); <--------------- change this
/* MySQL database password */
define( 'DB_PASSWORD', 'change-this-password' ); <--------------- change this
/* MySQL hostname, change the IP here if external DB set up */
define( 'DB_HOST', 'localhost' );
/* Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );
/* The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
Add Optional WordPress Settings
While you are already in wp-config.php, add a couple of sensible WordPress defaults for direct updates and a larger PHP memory limit.
/** ## Save files direct method ## */
define( 'FS_METHOD', 'direct' );
/** ## Increase memory limit, 256MB is recommended ## */
define('WP_MEMORY_LIMIT', '256M');
Keep the memory limit in line with the RAM you actually have. On a small VPS, 128M may be enough, while plugin-heavy sites often need 256M or more.
Configure WordPress Security Salt Keys on Ubuntu
Replace WordPress’s placeholder security salts before you finish the install. These values protect cookie signing and session data inside the application.
Generate a fresh set from the WordPress secret-key API, then replace the example lines in wp-config.php immediately.
Do not copy the salt keys shown in this article. They are examples only. Generate your own unique keys from the WordPress API and paste those values into your
wp-config.phpfile.
Open your wp-config.php file with a text editor to add the new security salt keys:
sudo nano /var/www/html/wordpress/wp-config.php
Then, find the lines in the file that correspond to the example keys:
define('AUTH_KEY', '<3yfS7/>%m.Tl^8Wx-Y8-|T77WRK[p>(PtH6V]Dl69^<8|K86[_Z},+THZ25+nJG');
define('SECURE_AUTH_KEY', 'bN#Qy#ChBX#Y`PE/_0N42zxgLD|5XpU[mu.n&:t4q~hg<UP/b8+xFTly_b}f]M;!');
define('LOGGED_IN_KEY', 'owpvIO-+WLG|,1)CQl*%gP1uDp}s(jUbYQ[Wm){O(x@sJ#T}tOTP&UOfk|wYsj5$');
define('NONCE_KEY', '8=Vh|V{D<>`CLoP0$H!Z3gEqf@])){L+6eGi`GAjV(Mu0YULL@sagx&cgb.QVCbi');
define('AUTH_SALT', '%TX*X$GE-;|?<-^(+K1Un!_Y<hk-Ne2;&{c[-v!{q4&OiJjQon /SHcc/:MB}y#(');
define('SECURE_AUTH_SALT', '=zkDT_%}J4ivjjN+F}:A+s6e64[^uQ<qNO]TfHS>G0elz2B~7Nk.vRcL00cJoo7*');
define('LOGGED_IN_SALT', '{$-o_ull4|qQ?f=8vP>Vvq8~v>g(2w12`h65ztPM(xo!Fr()5xrqy^k[E~TwI!xn');
define('NONCE_SALT', 'a1G(Q|X`eX$p%6>K:Cba!]/5MAqX+L<A4yU_&CI)*w+#ZB+*yK*u-|]X_9V;:++6');
Replace each example line with the unique salt line returned by the WordPress API. Save and exit the file once you have replaced every example value.
Configure the Nginx Server Block for WordPress on Ubuntu
Before the browser installer can load, Nginx needs a server block that points at the WordPress directory and forwards PHP requests to the correct PHP-FPM socket. Keep the try_files $uri $uri/ /index.php?$args; line intact, because dropping ?$args can break parts of the WordPress REST API.
Create a new server-block file and replace the example domain with your real host name:
sudo nano /etc/nginx/sites-available/example.com.conf
Use a configuration like the one below, then adjust the server names and keep the PHP socket matched to your release.
server {
listen 80;
listen [::]:80;
server_name www.example.com example.com;
root /var/www/html/wordpress;
index index.php index.html index.htm index.nginx-debian.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* /wp-sitemap.*\.xml {
try_files $uri $uri/ /index.php$is_args$args;
}
client_max_body_size 100M;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
include snippets/fastcgi-php.conf;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;
fastcgi_intercept_errors on;
}
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_proxied any;
gzip_disable "msie6";
gzip_types application/atom+xml application/geo+json application/javascript application/x-javascript application/json application/ld+json application/manifest+json application/rdf+xml application/rss+xml application/xhtml+xml application/xml font/eot font/otf font/ttf image/svg+xml text/css text/javascript text/plain text/xml;
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
expires 90d;
access_log off;
}
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
add_header Access-Control-Allow-Origin "*";
expires 90d;
access_log off;
}
location ~ /\.ht {
access_log off;
log_not_found off;
deny all;
}
}
Update the
fastcgi_passline to match your PHP version. The socket path format is/run/php/phpX.X-fpm.sockwhere X.X is your version number:
- Ubuntu 22.04:
fastcgi_pass unix:/run/php/php8.1-fpm.sock;- Ubuntu 24.04:
fastcgi_pass unix:/run/php/php8.3-fpm.sock;- Ubuntu 26.04:
fastcgi_pass unix:/run/php/php8.5-fpm.sock;
Enable and Test Nginx Configuration
Disable the default Nginx site if it is still present, then enable the WordPress server block.
sudo rm -f /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
Perform a dry run to check for any errors using the following command:
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
If the test passes, restart the Nginx service to apply your changes:
sudo systemctl restart nginx
Configure PHP Upload Limits for WordPress on Ubuntu
WordPress uploads often fail for predictable reasons: PHP allows a smaller payload than Nginx, or the default form and memory limits are too low for themes, plugins, and media imports. Fix those limits now instead of waiting for a 413 Request Entity Too Large error in the dashboard.
Open the php.ini file that matches your release:
# Ubuntu 22.04
sudo nano /etc/php/8.1/fpm/php.ini
# Ubuntu 24.04
sudo nano /etc/php/8.3/fpm/php.ini
# Ubuntu 26.04
sudo nano /etc/php/8.5/fpm/php.ini
Update the upload, post, execution, and memory limits to values that fit your site:
## Increase this to the maximum file size you want to upload ##
upload_max_filesize = 100M
## Increase this to the maximum post size you want to allow ##
post_max_size = 100M
## Increase this to the maximum execution time (seconds) ##
max_execution_time = 300
## Increase this for complex forms and plugins ##
max_input_vars = 5000
## Increase memory limit - ensure your system has enough RAM ##
memory_limit = 256M
Make sure the Nginx server block uses a matching body-size limit as well. Set client_max_body_size to the same value as upload_max_filesize, or slightly higher if you prefer.
Restart the matching PHP-FPM service after you save php.ini, then reload Nginx so both services pick up the new limits.
# Ubuntu 22.04
sudo systemctl restart php8.1-fpm
# Ubuntu 24.04
sudo systemctl restart php8.3-fpm
# Ubuntu 26.04
sudo systemctl restart php8.5-fpm
sudo systemctl reload nginx
Finish the WordPress Installation on Ubuntu
Open the site in a browser to finish the web-based installer. If the root URL does not redirect automatically, go straight to the installer path yourself.
Start with your domain, such as https://www.example.com. If WordPress has not redirected you yet, open https://www.example.com/wp-admin/install.php directly.
Choose a Language in the WordPress Installer on Ubuntu
The installer opens with the language screen. Choose the language you want for the WordPress dashboard, then continue.

Add Site Details in the WordPress Installer on Ubuntu
Enter the site title, admin username, password, and the main email address you want WordPress to use. Pick a strong password here, because this account controls the entire site.

If the site is still private or under construction, check the option that discourages search-engine indexing until you are ready to launch.
Run the WordPress Installer on Ubuntu
Submit the form to let WordPress write the first site settings and admin account. A successful run ends on the login screen.

Sign In to WordPress on Ubuntu
Sign in with the admin username and password you just created. That takes you straight to the dashboard where the site setup continues.

The dashboard is the control panel for themes, plugins, pages, users, and updates. From here, you can start publishing content, import an existing site, or harden the install before you put it into production.
Open the WordPress Dashboard on Ubuntu
At this point, WordPress is usable. The remaining work is the site itself: theme choice, plugins, media, menus, and whatever content structure your project needs.

Secure WordPress on Ubuntu and Fix Common Issues
Before you call the site finished, enable HTTPS and keep a few common WordPress-on-Nginx fixes nearby. The sections below cover the issues that show up most often on fresh installs.
Secure WordPress on Ubuntu with Let’s Encrypt
Move the site to HTTPS before you open it to real users. Certbot’s Nginx plugin can request the certificate, update the server block, and add the HTTP-to-HTTPS redirect for you.
If you want the standalone HTTPS walkthrough later, secure Nginx with Let’s Encrypt on Ubuntu.
Install Certbot and the Nginx plugin first:
sudo apt install python3-certbot-nginx -y
Request the certificate and let Certbot update the Nginx configuration in place:
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d www.example.com
Certbot asks whether you want renewal notices from the EFF. Choose whichever email preference fits your setup.
The command above enables HTTPS redirection, HSTS, and OCSP stapling as part of the initial setup.
When the certificate is in place, HTTP requests start redirecting to the HTTPS version of the site automatically.
Test renewal once so you know the certificate can renew cleanly:
sudo certbot renew --dry-run
Ubuntu’s packaged Certbot setup also enables a systemd timer by default, so verify the timer instead of creating a second renewal job in cron:
systemctl status certbot.timer --no-pager
● certbot.timer - Run certbot twice daily Loaded: loaded (/usr/lib/systemd/system/certbot.timer; enabled; preset: enabled) Active: active (waiting)
Fix WordPress PHP Session Errors on Ubuntu
Some plugins fail when PHP cannot write session data under /var/lib/php/sessions/. Reset the ownership if plugin logins, imports, or admin actions start throwing session-write errors.
sudo chown -R www-data:www-data /var/lib/php/sessions/
That returns the directory to the web-server user, which is usually enough to clear the session-write failure immediately.
Fix HTTPS Redirect Loops in WordPress on Ubuntu
If WordPress sits behind another proxy or load balancer, the admin area can get stuck in an HTTPS redirect loop because the forwarded protocol header is not reaching WordPress correctly.
Add the following snippet to wp-config.php to make WordPress respect the forwarded HTTPS header:
define('FORCE_SSL_ADMIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
$_SERVER['HTTPS'] = 'on';
}
This forces the admin area onto HTTPS and tells WordPress to treat requests forwarded as HTTPS as secure requests.
Open wp-config.php in a text editor to add it:
sudo nano /var/www/html/wordpress/wp-config.php
Paste it just before the line that says That's all, stop editing! Happy blogging., then save the file.
After that change, the admin area should stop bouncing between HTTP and HTTPS.
Fix Domain Redirect Loops in WordPress on Ubuntu
A second redirect-loop pattern shows up when the site URL stored in WordPress does not match the real domain name you are using.
Check the URL definitions in wp-config.php and make sure both values match the live site:
define('WP_HOME','https://example.com');
define('WP_SITEURL','https://example.com');
If either value points to the wrong host name, update it and reload the site.
If the values already match and the loop continues, recheck the Nginx server block and any reverse-proxy headers in front of WordPress.
Remove WordPress and the LEMP Stack on Ubuntu
If this host is dedicated to WordPress, you can remove the site files, database, and the Nginx, MariaDB, and PHP packages in one pass. If the server still hosts other sites or PHP applications, stop after the WordPress-specific cleanup and keep the shared packages installed.
Remove WordPress Files on Ubuntu
Delete the WordPress document root only after you have copied any themes, uploads, or configuration you still need.
The following command permanently deletes all WordPress files including themes, plugins, uploads, and configuration. Back up any data you want to keep before proceeding.
sudo rm -rf /var/www/html/wordpress/
Remove MariaDB and the WordPress Database on Ubuntu
First, drop the WordPress database and user before removing MariaDB:
sudo mariadb -u root -e "DROP DATABASE IF EXISTS wordpressdb; DROP USER IF EXISTS 'wpuser'@'localhost';"
If MariaDB only existed for this site, remove the packages next and review the autoremove list before you confirm it.
sudo apt purge mariadb-server mariadb-client -y
sudo apt autoremove
Remove PHP and WordPress Modules on Ubuntu
Remove the PHP-FPM, CLI, and WordPress extensions only when no other site on this server still depends on them.
sudo apt purge php-cli php-fpm php-mbstring php-bcmath php-xml php-mysql php-gd php-curl php-zip php-imagick php-intl -y
sudo apt autoremove
Remove Nginx from Ubuntu
Remove Nginx only if this machine no longer serves any other sites or reverse proxies.
sudo apt purge nginx -y
sudo apt autoremove
sudo rm -rf /etc/nginx/
Remove Let’s Encrypt Certificates on Ubuntu (Optional)
Delete the certificate only when the domain will not return to this server.
sudo certbot delete --cert-name www.example.com
sudo apt purge python3-certbot-nginx -y
WordPress on Ubuntu FAQ
Open your site root first, because WordPress often redirects there automatically after the files and Nginx server block are in place. If it does not, go straight to https://example.com/wp-admin/install.php to launch the installer manually.
Ubuntu uses versioned PHP-FPM units instead of a generic php-fpm.service name. Use php8.5-fpm on Ubuntu 26.04, php8.3-fpm on Ubuntu 24.04, or php8.1-fpm on Ubuntu 22.04, and check the available units with systemctl list-unit-files 'php*-fpm.service' if you are unsure.
Raise both the Nginx and PHP upload limits. In the Nginx server block, increase client_max_body_size, then in php.ini raise upload_max_filesize and post_max_size to matching values before you restart PHP-FPM and reload Nginx.
Not for this Nginx-based workflow. On Ubuntu 24.04 and 22.04, the broad php metapackage can pull Apache helpers into the stack, so it is safer to install php-cli, php-fpm, and only the WordPress extensions you actually need.
Conclusion
WordPress is now running on Ubuntu behind Nginx with MariaDB and PHP-FPM handling the backend, so the remaining work is site maintenance rather than stack assembly. For better performance, set up Nginx FastCGI cache on Ubuntu. If you postponed HTTPS earlier, secure Nginx with Let’s Encrypt on Ubuntu before the site goes live.
Hi brother, how are you? I followed your tutorial, but strangely it doesn’t work; I get a 404 error.