Cantech Knowledge Base

Your Go-To Hosting Resource

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

Setting up a LEMP stack — which includes Linux, Nginx, MySQL, and PHP — is a foundational step for hosting modern, dynamic web applications. This stack provides a powerful, open-source platform that’s lightweight, efficient, and widely supported across the web hosting industry.

Ubuntu 24.04, with its long-term support and up-to-date packages, is an excellent choice for deploying the LEMP stack. By combining the speed of the Nginx web server with the reliability of MySQL and the flexibility of PHP, developers can build and scale robust web applications with ease.

In this guide, you’ll learn how to install and configure each component of the LEMP stack on an Ubuntu 24.04 server. We’ll walk through setting up a sample PHP application, connecting it to a MySQL database, and securing the server with an SSL certificate from Let’s Encrypt — ensuring your site is ready for production.

Prerequisites

Before you begin:

Deploy an Ubuntu 24.04 instance on Vultr.

Create an A record for your domain (e.g., app.example.com) pointing to your server’s public IP.

Connect via SSH as a non-root user with sudo privileges.

Update your server packages:

sudo apt update && sudo apt upgrade -y

Step 1: Install Nginx Web Server

Install Nginx:

sudo apt install nginx -y

Start and enable Nginx to run on boot:

sudo systemctl start nginx

sudo systemctl enable nginx

Verify Nginx status:

sudo systemctl status nginx

You should see output confirming that the service is active and running.

Step 2: Install MySQL Database Server

Install MySQL:

sudo apt install mysql-server -y

Start and enable MySQL:

sudo systemctl start mysql

sudo systemctl enable mysql

Verify MySQL status:

sudo systemctl status mysql

Secure MySQL Installation

Run the security script:

sudo mysql_secure_installation

Recommended prompts:

Enable the VALIDATE PASSWORD plugin.
Choose STRONG policy (2).
Remove anonymous users.
Disallow remote root login.
Remove the test database.
Reload privilege tables.
Set a Root Password
Login to MySQL:

sudo mysql

Set a strong password and update authentication method:

sql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_secure_password';
FLUSH PRIVILEGES;
EXIT;

Restart MySQL:

sudo systemctl restart mysql

Step 3: Install PHP and Required Modules

Install PHP, PHP-FPM, and modules:

sudo apt install php php-fpm php-mysql php-cli -y

Verify PHP version:

php -v

Start and enable PHP-FPM:

sudo systemctl start php8.3-fpm
sudo systemctl enable php8.3-fpm
sudo systemctl status php8.3-fpm

Step 4: Configure PHP-FPM

Check PHP-FPM socket:

ss -pl | grep php

Navigate to PHP-FPM pool config directory:

cd /etc/php/8.3/fpm/pool.d/

the default pool config:

sudo nano www.conf

Ensure the following values are set:

ini
user = www-data
group = www-data
Adjust process manager settings if needed:
ini
pm.max_children = 10
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500

Save and exit.

Step 5: Configure Nginx to Use PHP-FPM

Create a PHP test file:

echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/index.php

Remove default configuration:

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

sudo rm /etc/nginx/sites-available/default

Create a new server block:

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

Add the following configuration:

nginx  
server {
    listen 80;
    server_name app.example.com;
    root /var/www/html;
    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;
    }
}

Enable the new config:

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

Test and restart Nginx:

sudo nginx -t

sudo systemctl restart nginx

Allow HTTP traffic through UFW:

sudo ufw allow 80/tcp

Visit http://app.example.com to confirm PHP is working.

Step 6: Secure Your Server with SSL

Allow HTTPS Traffic
Check available UFW profiles:

sudo ufw app list

Allow the full Nginx profile:

sudo ufw allow 'Nginx Full'

sudo ufw reload

sudo ufw status

Install Certbot and Get SSL Certificate
Install Certbot for Nginx:

sudo apt install python3-certbot-nginx -y

Obtain and configure the SSL certificate:

sudo certbot --nginx --agree-tos --redirect --email [email protected] -d app.example.com

Test auto-renewal:

sudo certbot renew --dry-run

Restart Nginx:

sudo systemctl restart nginx

Step 7: Test the LEMP Stack with a Sample App

Set Up the Database
Login to MySQL:

mysql -u root -p

Create database and user:

sql
CREATE DATABASE vultr_db;
USE vultr_db;
CREATE USER 'db_user'@'localhost' IDENTIFIED BY 'strong-password';
GRANT ALL PRIVILEGES ON vultr_db.* TO 'db_user'@'localhost';
FLUSH PRIVILEGES;

Create table and insert a record:

sql
CREATE TABLE IF NOT EXISTS VultrDocs (
  id INT AUTO_INCREMENT PRIMARY KEY,
  message VARCHAR(255) NOT NULL
);
INSERT INTO VultrDocs (message) VALUES ('Greetings from Vultr');
EXIT;

Create PHP Test File
Create the app file:

sudo nano /var/www/html/test.php

Paste the following:

php
<?php
$servername = "localhost";
$username = "db_user";
$password = "strong-password";
$dbname = "vultr_db";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
    die("Database Connection Failed: " . $conn->connect_error);
}
$sql = "SELECT message FROM VultrDocs";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
    $row = $result->fetch_assoc();
    echo "<h1>" . htmlspecialchars($row["message"]) . "</h1>";
} else {
    echo "<h1>No message found.</h1>";
}
$conn->close();
?>

Save and exit.

Test in Browser
Visit:
arduino

https://app.example.com/test.php

You should see:
Greetings from Vultr

Conclusion

You’ve successfully installed, configured, and secured a LEMP stack on Ubuntu 24.04. With Nginx serving as the web server, MySQL managing your databases, and PHP powering dynamic content, your server is now ready to host modern web applications. Secure your stack further with strong passwords, UFW rules, and regular updates.

April 30, 2025