Digity Republic

Tech News, Reviews, Deals, and How-To's

Installing LEMP (Linux, Nginx, MySQL, and PHP) on Ubuntu 20.04

Installing LEMP

image of Install LEMP

Introduction: Installing LEMP

Installing LEMP: A collection of programs known as the LEMP software stack may use to deliver PHP-coded dynamic web pages and web apps. An Nginx (pronounced “Engine-X”) web server runs on the Linux operating system, which refers to by this abbreviation. The dynamic processing is by PHP, while the backend data is kept in a MySQL database.

This tutorial shows you how to set up a LEMP stack on a server running Ubuntu 20.04. The first prerequisite takes care of the Ubuntu operating system. We’ll go over how to set the remaining parts up and functioning.


You must have access to an Ubuntu 20.04 server as a normal, non-root sudo user and have your server’s firewall activated in order to finish this guide. Follow our basic server setup tutorial for Ubuntu 20.04 to set this up.

Installing LEMP: 1. Installing the Nginx Web Server is step one.

We will use the high-performance web server Nginx to show web pages to visitors to our website. To get this software, we’ll make use of the apt package manager.

Update the package index on your server as this is our first time using apt in this session. After that, you can run the apt install to install Nginx:

sudo apt update
sudo apt install nginx

Enter Y to indicate that you wish to install Nginx when requested. The Nginx web server will be operational and operating on your Ubuntu 20.04 server after the installation is complete.

You must permit connections to Nginx if you have the ufw firewall activated, as advised in our initial server setup tutorial. Upon installation, Nginx registers a number of unique UFW application profiles. Run: to determine which UFW profiles are accessible.

sudo ufw app list
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS

It is advising that you activate the most stringent profile that yet permits the traffic you require. You simply need to permit standard HTTP traffic on port 80 since you didn’t establish SSL for your server in this step.

Type this to enable it:

sudo ufw allow 'Nginx HTTP'

You may test the modification by executing:

sudo ufw status

The result of this operation will demonstrate that HTTP traffic now permit:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

You may check if the server is up and operating after the new firewall rule was implemented going to the server’s domain name or public IP address in your web browser.

The following command can use to discover your server’s public IP address if you don’t know it and don’t have a domain name directed to it:

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

A few IP addresses will print as a result. You may use your web browser to test each one in turn.

As an alternative, you can determine which IP address is reachable from different parts of the internet:

curl -4 icanhazip.com

You may access Nginx’s default landing page by typing the address you get into your web browser:

Installing LEMP

If you can view this page, your web server has been configured to accept HTTP traffic and Nginx has been successfully deployed.

Installing LEMP: Installing MySQL in Step 2

Installing LEMP: After setting up a web server, you must set up a database system so that you can manage and store data for your website. A common database management system used in PHP settings is MySQL.

Once more, get and set up these applications using apt:

sudo apt install mysql-server

When asked, enter after entering Y to confirm the installation.

It advises that you execute a security script that is pre-installed with MySQL after the installation is complete. This script will lock down access to your database system and remove several unsafe default settings. Run the interactive script to get it going.

sudo mysql_secure_installation

When asked, enter after entering Y to confirm the installation.

It advise that you execute a security script that pre-installs with MySQL after the installation is complete. This script will lock down access to your database system and remove several unsafe default settings. Run the interactive script to get it going.

To continue without enabling, respond with Y for yes or with anything else.

VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No:

You will prompt to choose a degree of password validation if you respond “yes.” Remember that if you choose the toughest level of 2 and try to make a password that doesn’t include digits, upper and lowercase letters, special characters, or is based on a word from a common dictionary, you will get problems.

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary              file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1

Your server will then request that you choose and confirm a password for the MySQL root user, regardless of whether you decided to configure the VALIDATE PASSWORD PLUGIN. Contrast this with the system root to avoid confusion. The database root user has complete control over the database system and is an administrator user. Even though the MySQL root user’s default authentication mechanism disallows the usage of passwords even when they are set, you should establish a strong password here as an extra layer of security. In a bit, we’ll talk about this.

Your server will ask you to proceed after displaying the password strength for the root password you just supplied if you enabled password validation.

Estimated strength of the password: 100 
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y

To answer the remaining questions, press Y and then press the ENTER key when prompted. This will stop remote root logins, delete some anonymous users, delete the test database, load these new rules, and make sure MySQL quickly complies with your modifications.

Once you’re done, type the following to see if you can access the MySQL console:

sudo mysql

The use of sudo while running this command implies that it will connect to the MySQL server as the administrator database user root. The output should be as follows:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 8.0.19-0ubuntu5 (Ubuntu)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


To exit the MySQL console, type:


Even though you specified a password when you ran the mysql secure installation script, you didn’t need to enter it in order to join as the root user. This is due to the administrator MySQL user’s default authentication method, UNIX socket, not using a password. Even though this might at first appear to a security risk, it actually increases the security of the database server because only system users with sudo privileges connecting from the console or through an application running with the same privileges are permitted to log in as the root MySQL user. In real words, that implies your PHP application won’t able to connect using the administrative database root account. It’s possible to secure the root MySQL account using a password.

Especially if you intend to host many databases on your server, it recommend to set up separate user accounts with fewer rights for each database in order to boost security.

Note: At the time of writing, MySQL 8’s default authentication mechanism, caching sha2 authentication, is not supported by the native MySQL PHP library mysqlnd. Because of this, you must ensure that database users created for PHP applications running on MySQL 8 are set up to utilize mysql native password instead. In Step 6, we’ll show you how to achieve it.

Your MySQL server has now been set up and is protected. The final element of the LEMP stack, PHP, will then install.

Step 3: PHP Installation

Nginx is set up to deliver content, and MySQL is set up to store and handle data. To process code and provide dynamic content for the web server, PHP may now install.

Nginx needs an extra application to handle PHP processing and serve as a bridge between the PHP interpreter itself and the web server, whereas Apache embeds the PHP interpreter in each request. Most PHP-based websites can run better overall thanks to this, although it necessitates additional settings. Install “PHP FastCGI process manager,” also known as “PHP-fpm,” and instruct Nginx to forward PHP requests to this program for processing. You also require PHP-mysql, a PHP module that enables the communication between PHP and MySQL-based databases.

sudo apt install php-fpm php-mysql

Enter Y and ENTER to confirm installation when asked.

Your PHP components are now installing. The next step is to set up Nginx to utilize them.

Installing LEMP: 4. Configuring Nginx to Use the PHP Processor

The Nginx web server allows us to establish server blocks, which are analogous to virtual hosts in Apache and allow us to host several domains on a single server by encapsulating configuration information. We’ll use the domain name your domain as an example throughout this article. See our introduction to DigitalOcean DNS for more information on setting up a domain name with them.

On Ubuntu 20.04, Nginx is set up to serve content from a directory located at /var/www/Html and comes with one server block activating by default. Although this is effective for a single site, managing many sites can challenge. We’ll establish a directory structure within /var/www for your domain instead of changing /var/www/Html.

sudo mkdir /var/www/your_domain
sudo chown -R $USER:$USER /var/www/your_domain
sudo nano /etc/nginx/sites-available/your_domain

This will produce a brand-new, empty file. Paste the basic setup shown below:

server {
    listen 80;
    server_name your_domain www.your_domain;
    root /var/www/your_domain;

    index index.html index.htm index.php;

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

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

    location ~ /\.ht {
        deny all;


Here is what each of these location blocks and directives accomplishes:

listen — Specifies the port on which Nginx will listen. The HTTP standard port 80 will use in this instance as a listening port.
root — Describes the document root in which this website’s files are kept.
index — Sets the order in which Nginx will give preference to index files for this website. Index.html files are frequently listed before index.php files in PHP programs so that a maintenance landing page may create. To better meet the requirements of your application, you can change these variables.

Which domain names and/or IP addresses this server block should reply to determine by server name? Set this directive to the public IP address or domain name of your server.
address / — A try files directive that searches for files or folders matching a URI request is present in the first location block. A 404 error will send to Nginx if the correct resource cannot find.
the location.php
$ — By directing Nginx to the FastCGI-PHP.conf configuration file and the php7.4-fpm.sock file, which specifies what socket is connecting to PHP-fpm, this location block manages the actual PHP execution.

location /.ht — Nginx does not process. htaccess files, thus this location block deals with them. by including any applicable reject all directives.

Visitors won’t serve any. htaccess files that accidentally make their way into the page root.
Save your changes and then exit the file. If you’re using nano, you may confirm by entering CTRL+Y, followed by y, then ENTER.

Link to the configuration file from the sites-enabled directory of Nginx to activate your setup:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
sudo unlink /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/

When Nginx is loading again, later on, this will instruct it to utilize the settings. By typing: you may check your setup for syntactic mistakes.

sudo nginx -t

Go back to your configuration file and check its contents if any problems are displaying before continuing.

Reload Nginx to implement the modifications when you’re ready:

sudo systemctl reload nginx

Although the web root, /var/www/your domain, is now live, it is still empty. Create an index.html file there so that we can check to see if your new server block functions as intended:

nano /var/www/your_domain/index.html
    <title>your_domain website</title>
    <h1>Hello World!</h1>

    <p>This is the landing page of <strong>your_domain</strong>.</p>

Visit your server’s domain or IP address in your browser by typing it into your server block configuration file’s server name directive:

Installing LEMP

Installing LEMP: 5. Testing PHP with Nginx in Step 5

Create a test PHP file in your document root to do this. At your text editor, launch a new file calling info.php in the document root:

nano /var/www/your_domain/info.php
sudo rm /var/www/your_domain/info.php

Installing LEMP: Step 6: PHP Database Connection Testing (Optional)

Create a test table with fictitious data and run a PHP script to query its contents to see if PHP can connect to MySQL and do database queries. Before doing that, we must first establish a test database and a new MySQL user with the necessary access permissions.

Do You Need More Help?

Visit our forum, describe your question briefly and get answers