How to Set Up a LEMP Stack (Linux, Nginx, MySQL, PHP)
Build a complete LEMP stack on Ubuntu 24.04 — Nginx, MySQL, and PHP-FPM — and serve a working PHP site with clean, correct config.

LEMP is the modern web stack: Linux, Nginx (the "E" is for its pronunciation, engine-x), MySQL, and PHP. It powers WordPress, Laravel, and countless PHP applications, using less memory than the older Apache-based LAMP stack. This guide builds a complete LEMP stack on Ubuntu 24.04 and serves a working PHP page.
The four pieces
- Linux: your Ubuntu 24.04 VPS.
- Nginx: the web server, handling requests and static files.
- MySQL: the database.
- PHP-FPM: a fast PHP process manager Nginx talks to over a socket.
Unlike Apache, Nginx does not embed PHP — it hands PHP requests to PHP-FPM. That separation is what makes LEMP lean.
Install Nginx
sudo apt update
sudo apt install nginx -y
sudo ufw allow 'Nginx Full'
If you want the full walkthrough, see installing Nginx on Ubuntu 24.04.
Install MySQL
sudo apt install mysql-server -y
sudo mysql_secure_installation
Work through the security prompts as described in our MySQL install and secure guide, then create an app database and user for your site.
Install PHP-FPM
Install PHP-FPM and the MySQL driver:
sudo apt install php-fpm php-mysql -y
Check which version installed (Ubuntu 24.04 ships PHP 8.3):
php -v
systemctl status php8.3-fpm
Note the socket path — it will be /run/php/php8.3-fpm.sock.

Configure Nginx to process PHP
Create a web root and an Nginx server block that passes .php files to PHP-FPM. Make the root:
sudo mkdir -p /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
Create /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/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
The location ~ \.php$ block is the heart of it — it forwards PHP execution to the FPM socket. Adjust the version in the socket path if yours differs. Enable and reload:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Test PHP processing
Drop a test file:
echo '<?php phpinfo();' | sudo tee /var/www/example.com/info.php
Visit http://example.com/info.php and you should see the PHP info page. Delete it afterwards — it leaks server details:
sudo rm /var/www/example.com/info.php
Add HTTPS and go live
Point your domain at the server (how to point a domain to your VPS) and add a free certificate with Certbot. Your LEMP stack is now ready for WordPress, Laravel, or any PHP app.
Tune PHP-FPM and enable OPcache
PHP-FPM runs a pool of worker processes, and its defaults suit larger servers. On a small VPS, trim the pool in /etc/php/8.3/fpm/pool.d/www.conf:
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Each child uses memory, so max_children times your average PHP memory should fit comfortably in RAM. Next, make sure OPcache is on — it compiles PHP once and caches the bytecode, a large speed win. It ships enabled on Ubuntu; confirm in /etc/php/8.3/mods-available/opcache.ini:
opcache.enable=1
opcache.memory_consumption=128
Restart after changes:
sudo systemctl restart php8.3-fpm
Verify the whole stack
A quick end-to-end test: create a PHP file that connects to MySQL and prints a query result. If the page renders data, Nginx, PHP-FPM, and MySQL are all talking to each other — the three tiers of your LEMP stack confirmed working together.
FAQ
LEMP vs LAMP — what is the real difference?
LAMP uses Apache with PHP embedded via mod_php; LEMP uses Nginx with PHP handed off to PHP-FPM. LEMP typically uses less memory and handles concurrency better; LAMP is friendlier if you depend on .htaccess. See our Apache install guide for the Apache side.
Why does my browser download the PHP file instead of running it?
Nginx is not passing PHP to FPM. Check the location ~ \.php$ block exists, the fastcgi_pass socket path matches your installed PHP version, and that you reloaded Nginx.
Which PHP version ships with Ubuntu 24.04?
PHP 8.3, so the FPM socket is /run/php/php8.3-fpm.sock. If you install a different version from a PPA, update the socket path in your server block to match.
How do I raise the PHP upload limit?
Edit upload_max_filesize and post_max_size in /etc/php/8.3/fpm/php.ini, then sudo systemctl restart php8.3-fpm. Also raise client_max_body_size in your Nginx server block, since both limits apply.
Nxeon WordPress and PHP hosting on a VPS gives you full root to run LEMP exactly how you like on fast NVMe — with one-click images and free migration help to move a PHP site across.