LEMP Stack Howsnip

How to Install LEMP Stack on Ubuntu (Nginx, MySQL 8.4, PHP 8.5)

Setting up a web server is one of the first tasks when deploying PHP applications such as WordPress, Laravel, Magento, or custom PHP projects. A popular choice is the LEMP stack, which combines Linux, Nginx, MySQL, and PHP to deliver dynamic websites efficiently.

In this tutorial, you’ll learn how to install and configure a complete LEMP stack on Ubuntu. By the end, you’ll have:

  • Nginx serving web requests
  • MySQL 8.4 handling database operations
  • PHP 8.5 processing PHP applications through PHP-FPM
  • A working PHP and MySQL connection test

Quick Reference

Useful commands you’ll use throughout this guide:

  • sudo apt update – Update the package index.
  • sudo apt install nginx – Install Nginx.
  • sudo apt install mysql-server – Install MySQL Server.
  • sudo apt install php-fpm php-mysql – Install PHP-FPM and the MySQL extension.
  • sudo mysql_secure_installation – Run MySQL security hardening.
  • sudo systemctl restart php8.5-fpm – Restart PHP-FPM.
  • sudo systemctl reload nginx – Reload Nginx configuration.
  • sudo nginx -t – Test Nginx configuration syntax.
  • sudo ufw allow ‘Nginx Full’ – Allow HTTP and HTTPS traffic through the firewall.
  • /run/php/php8.5-fpm.sock – PHP-FPM Socket Location

Prerequisites

Before you begin, make sure you have:

  • An Ubuntu server.
  • A user account with sudo privileges.
  • UFW (Uncomplicated Firewall) enabled and configured.

Note: If you’re working on a production server, it’s recommended to apply system updates before installing any new software.

Step 1: Install Nginx

Nginx is the web server component of the LEMP stack. It handles incoming HTTP and HTTPS requests and serves website content.

a) Update Package Information

Refresh the local package list:

sudo apt update

LEMP Install Howsnip

This ensures Ubuntu downloads the latest available packages.

b) Install Nginx

Install the Nginx package:

sudo apt install nginx

LEMP Install Howsnip

Once installation finishes, Nginx should start automatically.

c) Verify Nginx Status

Check that the service is running:

sudo systemctl status nginx

LEMP Install Howsnip

Look for:

active (running)

This confirms the web server is operational.

d) Allow Web Traffic Through the Firewall

If UFW is enabled, allow HTTP and HTTPS traffic:

sudo ufw allow 'Nginx Full'

This creates firewall rules for both ports 80 and 443.

e) Test Nginx

Open the following URL in your browser:

http://your_server_ip

LEMP Install Howsnip

You should see the default Nginx welcome page.

Step 2: Install MySQL

MySQL provides the database backend used by most PHP websites and web applications.

a) Install MySQL Server

Run:

sudo apt install mysql-server

LEMP Install Howsnip

The installation may take a few minutes depending on your server and network connection.

b) Secure the MySQL Installation

Execute the built-in security script:

sudo mysql_secure_installation

LEMP Install Howsnip

This utility helps improve the security of your database server by:

  • Removing anonymous users
  • Disabling remote root logins
  • Deleting the default test database

c) Applying additional security settings

When prompted, answer Y to the hardening recommendations.

Note: The Validate Password component is optional. You can disable it if you prefer to manage password policies yourself.

d) Confirm MySQL Is Running

Check the service status:

sudo systemctl status mysql

LEMP Install Howsnip

The output should indicate that MySQL is active and running.

Step 3: Install PHP and PHP-FPM

Nginx does not process PHP code directly. Instead, it forwards PHP requests to PHP-FPM (FastCGI Process Manager), which executes the PHP scripts.

a) Install PHP-FPM and MySQL Support

Update package information and install PHP:

sudo apt update
sudo apt install php-fpm php-mysql

LEMP Install Howsnip

This installs PHP 8.5 together with the MySQL extension.

b) Verify the PHP Version

Check the installed version:

php -v

LEMP Install Howsnip

You should see output beginning with:

PHP 8.5.x

c) Verify PHP-FPM Status

Confirm the PHP-FPM service is running:

sudo systemctl status php8.5-fpm

LEMP Install Howsnip

PHP-FPM listens on the following Unix socket:

/run/php/php8.5-fpm.sock

d) Install Additional PHP Extensions (Optional)

Many PHP applications require additional modules.

Install commonly used extensions:

sudo apt install php-curl php-gd php-mbstring php-xml php-zip

LEMP Install Howsnip

These extensions provide functionality such as image processing, XML handling, string manipulation, and ZIP archive support.

Step 4: Configure Nginx to Process PHP Files

With Nginx and PHP-FPM installed, the next step is configuring Nginx to send PHP requests to PHP-FPM.

a) Create a Website Directory

Create the document root:

sudo mkdir -p /var/www/example.com

Assign ownership to your user account:

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

LEMP Install Howsnip

Replace example.com with your actual domain if available.

b) Create a New Server Block

Create a configuration file:

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

LEMP Install Howsnip

Add the following configuration:

server {
listen 80;
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.5-fpm.sock;
}

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

Understanding the Configuration

  • server_name defines the domain name served by this site.
  • root specifies the website files location.
  • index index.php index.html sets the default files.
  • try_files checks whether the requested file exists before returning a 404 error.
  • location ~ \.php$ forwards PHP requests to PHP-FPM.
  • location ~ /\.ht blocks access to .htaccess files.

c) Enable the Site

Create a symbolic link:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

d) Disable the Default Site (Optional)

If the default site is still enabled:

sudo unlink /etc/nginx/sites-enabled/default

This prevents conflicts with your new configuration.

e) Test the Configuration

Validate the Nginx configuration before applying it:

sudo nginx -t

LEMP Install Howsnip

Successful output ends with:

syntax is ok
test is successful

f) Reload Nginx

Apply the configuration:

sudo systemctl reload nginx

Step 5: Verify PHP Processing

Before deploying applications, verify that Nginx is correctly processing PHP files.

a) Create a PHP Test File

Run:

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

LEMP Install Howsnip

This creates a simple PHP file that displays PHP configuration details.

b) Open the Test Page

Visit:

http://example.com/info.php

or

http://your_server_ip/info.php

LEMP Install Howsnip

If everything is configured correctly, you’ll see the PHP information page.

Troubleshooting: If the browser displays the PHP code as plain text instead of executing it, review the location ~ \.php$ section in your Nginx configuration.

c) Remove the Test File

After verification, delete the file:

sudo rm /var/www/example.com/info.php

Warning: The phpinfo() page exposes system and PHP configuration details and should never remain publicly accessible.

Step 6: Test MySQL Connectivity from PHP

The final test confirms that PHP can connect to MySQL successfully.

a) Create a Test Database and User

Open the MySQL console:

sudo mysql

Run the following SQL commands:

CREATE DATABASE lemp_test;
CREATE USER 'lemp_user'@'localhost' IDENTIFIED BY 'changeme';

LEMP Install Howsnip

GRANT ALL PRIVILEGES ON lemp_test.* TO 'lemp_user'@'localhost';

LEMP Install Howsnip

FLUSH PRIVILEGES;
EXIT;

LEMP Install Howsnip

Warning: Replace changeme with a strong password before using this setup in production.

b) Create a PHP Database Test File

Create the file:

sudo nano /var/www/example.com/db-test.php

LEMP Install Howsnip

Add the following code:

<?php
$mysqli = new mysqli("localhost", "lemp_user", "changeme", "lemp_test");

if ($mysqli->connect_error) {
die("Connection failed: " . $mysqli->connect_error);
}

echo "Connected to MySQL " . $mysqli->server_info;

$mysqli->close();

This script attempts to connect to MySQL and displays the server version when successful.

c) Test the Database Connection

Open:

http://example.com/db-test.php

LEMP Install Howsnip

A successful connection displays a message similar to:

Connected to MySQL 8.4.x

d) Remove the Test File

After confirming connectivity:

sudo rm /var/www/example.com/db-test.php

Removing the file helps reduce unnecessary exposure of database connection information.

Conclusion

You have successfully installed and configured a complete LEMP stack on Ubuntu. Nginx is now serving web requests, MySQL 8.4 is handling database operations, and PHP 8.5 is processing dynamic content through PHP-FPM.

After completing these tests, your server is ready to host PHP-based applications such as WordPress, Laravel, Magento, and other modern web projects. For production deployments, consider adding SSL certificates, regular backups, database security policies, and ongoing system updates to keep your server secure and reliable.