Linux

Set up LEMP Stack Nginx MariaDB PHP 8.3 on Ubuntu 24.04

You've provisioned a fresh Ubuntu 24.04 VPS, and you need a web stack that can actually handle traffic. Not Apache's memory overhead, not MySQL's license headaches. The LEMP stack, Nginx, MariaDB, PHP 8.3, is the no-nonsense choice for production workloads. By the end of this guide, you'll have a fully functional LEMP stack running on your Linux VPS, verified at every step, and ready to serve your application.

  • Nginx, event-driven, asynchronous web server that handles thousands of concurrent connections without breaking a sweat.
  • MariaDB, drop-in MySQL replacement, community-driven, no Oracle baggage.
  • PHP 8.3, latest stable branch with major performance improvements over previous versions.

Prerequisites

  • An Ubuntu 24.04 VPS with root or a sudo-enabled user.
  • A non-root user with sudo privileges (create one if you're logged in as root: adduser username && usermod -aG sudo username).
  • Basic familiarity with the terminal and SSH.
  • Firewall enabled (ufw) and SSH port allowed.

Why the LEMP Stack Still Matters in 2026

You might be tempted to reach for a one-click installer or a Docker compose file. Those are fine for development. But when you need to own your stack, tune it, touch the configs, understand the failure modes, you install it yourself. The LEMP stack gives you four distinct processes that you control independently:

  • Nginx handles static files and reverse-proxies PHP requests to FPM. It does not execute PHP.
  • PHP-FPM runs as a separate service, pools of workers managed independently from Nginx.
  • MariaDB listens on its own socket, completely decoupled from the web server.
  • Systemd manages all three, so you restart one without affecting the others.

This separation is why LEMP outperforms Apache+mod_php on a 2GB RAM VPS under concurrent load. Each component does one thing and does it well.

Step 1, Install Nginx

Ubuntu 24.04 ships with Nginx 1.24 or later in its repositories. We'll use the official package, no compiling from source needed for standard setups.

sudo apt update
sudo apt install nginx -y

Now open port 80 in the firewall so users can hit your web server.

sudo ufw allow 'Nginx Full'
sudo ufw enable   # if not yet enabled

Verify Nginx is running and listening:

systemctl status nginx
# Should show "active (running)"
ss -tlnp | grep :80
# Should show nginx listening on 0.0.0.0:80

Point your browser to your VPS's IP address. You should see the default Nginx welcome page.

Step 2, Install MariaDB

MariaDB is the default MySQL-compatible database on Ubuntu 24.04. The package name is mariadb-server.

sudo apt install mariadb-server mariadb-client -y

After installation, run the security script to remove anonymous users, disable remote root login, and remove test databases.

sudo mysql_secure_installation

Follow the prompts. Say Y to everything except "Change the root password?" if you're using the unix_socket authentication plugin (which is the default on Ubuntu 24.04 and secure enough for single-server setups).

Verify MariaDB is running:

systemctl status mariadb
sudo mysql -u root -e "SELECT VERSION();"
# Should return the MariaDB version

Step 3, Install PHP 8.3 and PHP-FPM

Ubuntu 24.04 includes PHP 8.3 in its repositories. We need php-fpm (FastCGI Process Manager) and a set of commonly used extensions.

sudo apt install php8.3-fpm php8.3-cli php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip -y

Verify PHP is installed and the FPM service is running:

php -v
# Should show PHP 8.3.x
systemctl status php8.3-fpm
# Should show "active (running)"
ss -tlnp | grep :9000
# PHP-FPM listens on 127.0.0.1:9000 by default

If you plan to run multiple sites or need different PHP settings per site, you'll configure pool files later in /etc/php/8.3/fpm/pool.d/.

Step 4, Configure Nginx to Process PHP

Now we wire Nginx to PHP-FPM. Create a server block (virtual host) for your site. I'll use example.com, replace with your domain.

sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com/html

Create the config file:

sudo nano /etc/nginx/sites-available/example.com

Paste the following:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    root /var/www/example.com/html;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Enable the site and test the configuration:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
# Should output: syntax is ok and test is successful

Reload Nginx to apply the changes:

sudo systemctl reload nginx

Test PHP processing:

echo "" | sudo tee /var/www/example.com/html/info.php

Visit http://example.com/info.php in your browser. You should see the PHP info page. Remove this file after testing, it exposes sensitive server information.

Step 5, Secure Your Database User and Connection

Do not use the MariaDB root account from your web application. Create a dedicated database and user.

sudo mariadb -u root
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myappuser'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON myapp.* TO 'myappuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Verify the new user can connect:

mariadb -u myappuser -p -e "SHOW DATABASES;"
# Should list the myapp database among the defaults

Troubleshooting

1. Nginx returns 404 for .php files. Check that fastcgi_pass points to the correct socket path. Run ls /var/run/php/ to see the socket file name. On some systems it's php8.3-fpm.sock, on others just php-fpm.sock.

2. "502 Bad Gateway" from Nginx. PHP-FPM is not running or the socket path is wrong. Check with systemctl status php8.3-fpm and restart it: sudo systemctl restart php8.3-fpm. Then check the socket file exists in /var/run/php/.

3. MariaDB won't start after install. Check the error log: sudo tail -20 /var/log/mysql/error.log. Common cause, the data directory is full or permissions are wrong. On Ubuntu 24.04, the directory is /var/lib/mysql with owner mysql:mysql.

4. Need to install additional PHP extensions? Run sudo apt search php8.3- to list all available extensions, then install the ones you need.

FAQ

What is the difference between LEMP and LAMP?

LEMP uses Nginx (pronounced "Engine-X") as the web server instead of Apache. Nginx is event-driven, handling thousands of concurrent connections with less memory. LAMP uses Apache, which is process-driven and consumes more RAM per connection. For a low-resource VPS, LEMP is almost always the better choice.

Can I use MySQL instead of MariaDB?

Yes. Replace mariadb-server with mysql-server in Step 2. The rest of the guide works the same, MariaDB is a drop-in replacement with nearly identical syntax. However, MariaDB is the default on Ubuntu 24.04 and has better community support.

Do I need all the PHP extensions listed in Step 3?

No. The list covers common applications (WordPress, Laravel, Drupal). If you know your app needs fewer extensions, install only what's required. You can always add later.

Should I use a Unix socket or TCP for PHP-FPM?

Unix socket (unix:/var/run/php/php8.3-fpm.sock) is faster because it avoids TCP overhead. TCP (127.0.0.1:9000) is useful if you run PHP-FPM on a separate machine. For a single VPS, use the socket.

How do I restart the entire stack?

Run sudo systemctl restart nginx php8.3-fpm mariadb. Each service is independent; you can restart one without affecting the others. For example, restarting Nginx does not drop database connections.

Related articles

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.