How to Install a LEMP Stack (Nginx, MySQL, PHP) on Ubuntu 24.04 Print

  • 0

The LEMP stack swaps Apache for Nginx (pronounced “engine-x”, hence the E): Linux, Engine-X (Nginx), MySQL, PHP. Nginx's event-driven architecture serves thousands of concurrent connections with a fraction of Apache's memory, which is why it is the default choice for busy sites and small VPS plans alike. Here is the full Ubuntu 24.04 installation, including the PHP-FPM wiring most tutorials get wrong.

Step 1 — Install Nginx, MySQL and PHP-FPM

sudo apt update
sudo apt install nginx mysql-server php-fpm php-mysql -y
Installing the LEMP stack Nginx MySQL PHP-FPM on Ubuntu 24.04

Nginx does not embed PHP the way Apache does — PHP runs as a separate PHP-FPM service that Nginx forwards requests to. Allow web traffic:

sudo ufw allow "Nginx Full"

Step 2 — Secure MySQL

Exactly as with the LAMP stack: run sudo mysql_secure_installation, then create a dedicated database and user for the application.

Step 3 — Configure the server block

sudo mkdir -p /var/www/example.com
sudo nano /etc/nginx/sites-available/example.com
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php index.html;

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

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

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

Enable it and drop the default site:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Testing Nginx configuration with nginx -t and verifying HTTP 200 response

Step 4 — Test PHP-FPM

echo '<?php phpinfo();' | sudo tee /var/www/example.com/info.php

Browse to http://your_server_ip/info.php; the “Server API” line should read FPM/FastCGI. Delete the file when done.

Step 5 — Tune PHP-FPM for your RAM

The default pool allows more PHP workers than a small VPS can feed. On a 2 GB server, edit /etc/php/8.3/fpm/pool.d/www.conf:

pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
sudo systemctl reload php8.3-fpm

If your site dies under load with “server reached pm.max_children” in the logs, that value is the dial to turn — alongside adding swap as a safety net.

Common errors

502 Bad Gateway almost always means Nginx cannot reach PHP-FPM — check the socket path in your server block matches ls /run/php/. 413 Request Entity Too Large on uploads: raise client_max_body_size 64m; in the server block and upload_max_filesize in php.ini.

Next steps

Add a free SSL certificate with Certbot (it has a native Nginx plugin), enable unattended security updates, and monitor the stack with the tools in our performance monitoring guide.

Related Ubuntu guides

Prefer to have experts handle it?

LFA IT provides fully managed Ubuntu VPS and dedicated servers — initial setup, security hardening, monitoring and 24/7 support, so you can focus on your business. Explore our hosting and server management services or open a support ticket and our engineers will take it from there.


Was this answer helpful?

« Back