How to install LEMP stack on Ubuntu 22.04 LTS

Ubuntu is one the most popular Linux distributions. Ubuntu is a free and open-source software based on Debian. In this simple I will walk you through the whole process to install a LEMP stack (Linux, Ngnix, MySQL/Maridb & PHP) which I am going to use for a brand new WordPress website later on.

What is a LEMP Stack?

The Ubuntu LEMP stack (Linux, (E)Nginx, MySQL, PHP) is a substitute for the original LAMP Stack (Linux, Apache, MySQL, PHP). Both stacks allow users to host web applications and implement a fully-functional programming environment. Additionally, the main components of both the LAMP and LEMP stacks can be installed using the default Ubuntu software repository.

In most cases, a LEMP stack uses the MariaDB database. MariaDB is a community-developed, commercially supported fork of the MySQL relational database management system, intended to remain free and open-source software under the GNU General Public License. You can also use MySQL in LEMP stack though.

Preparing a new server

I will start with creating a new server on Linode Cloud and get root ssh access to my new linode server. In this tutorial, I use Ubuntu 22.04 LTS fo new server instance but this article should apply to Ubuntu 20.04 LTS release since they are very similar.

(Once I have got ssh access to my new linode server I will get back to this post so be ready to ssh to your server . (In the meantime I will also configure the server to disable root access to server and enable non root user with ssh key pair only.)

Install ALL components!

The various LEMP stack components can be installed using the apt utility. To install the LEMP stack, follow these steps. In all cases, enter y to proceed with the installation when Ubuntu asks for confirmation.

Note: Each component can immediately be configured after installation, but it’s usually easier to install all the applications first and configure them later. 

  1. Use apt to update the Ubuntu packages.
    sudo apt update && sudo apt upgrade
  2. Install the NGINX server.
    sudo apt install nginx
  3. Install the NGINX server.
    sudo apt update && sudo apt upgrade
  4. Confirm NGINX is properly running using the systemctl utility.
    sudo systemctl status nginx
    nginx.service - A high performance web server and a reverse proxy server
         Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
         Active: active (running) since Sat 2023-07-29 08:11:15 UTC; 1min 41s ago
  5. Install the MariaDB database.
    sudo apt install mariadb-server
  6. Install the PHP module for MariaDB/MySQL support.
    Note
    Do not install the main php module because it is optimized for Apache. PHP support for NGINX is installed later.
    sudo apt install php-mysql
  7. Install the PHP FastCGI Processing Manager. This includes all the PHP packets necessary for NGINX support, along with other core dependencies.
    sudo apt install php-fpm

    Note: By default Ubuntu 22.04 has the PHP 8.1 repository. You may also try to install 

  8. (Optional) Other applications, including WordPress, require additional PHP components. The following optional packages are frequently helpful.
    sudo apt install php-curl php-gd php-mbstring php-xml php-xmlrpc

Configuring LEMP Stack on Ubuntu

At this point, all LEMP Stack components are installed, but LEMP stack is not ready to use yet. The individual elements must be configured or enabled. The following sections explain how to configure a LEMP stack on Ubuntu 22.04.

Configuring NGINX

  1. Configure the ufw firewall so it accepts NGINX connections. Allow the Nginx Full profile, which permits both HTTP and HTTPS connections. Ensure OpenSSH connections are also allowed. Enable ufw when all changes are complete.
    sudo ufw allow OpenSSH 
    sudo ufw allow in "Nginx Full" 
    sudo ufw enable
  2. Verify the firewall settings using the ufw status command.
    sudo ufw status
    Status: active
    
    To                         Action      From
    --                         ------      ----
    OpenSSH                    ALLOW       Anywhere                  
    Nginx Full                 ALLOW       Anywhere                  
    OpenSSH (v6)               ALLOW       Anywhere (v6)             
    Nginx Full (v6)            ALLOW       Anywhere (v6)
  3. After configuring the firewall, ensure NGINX allows web access. Using a browser, visit the IP address of the web server. The site displays the default NGINX welcome page. The page includes the message “Welcome to nginx!”
    http://server_IP_address/

  4. Create a root directory for the site. For example, create this directory within the /var/www/html/ directory, where example.com is the name of the site. In the following command, replace example.com with the actual name of the domain.
    sudo mkdir -p /var/www/html/example.com
  5. I will copy over the default NGINX configuration file to /etc/nginx/sites-available/example.com.conf. Replace example.com with the name of the domain. The new configuration file must have the .conf extension.
    File: /etc/nginx/sites-available/example.com.conf

    server {
        listen 80;
        listen [::]:80;
    
        server_name example.com www.example.com;
        root /var/www/html/example.com;
        index index.html;
    
        location / {
            try_files $uri $uri/ =404;
        }
    
        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
            include snippets/fastcgi-php.conf;
        }
    
        location ~ /\.ht {
            deny all;
        }
    }
  6. To enable the site, create a link to the domain configuration file from the sites-enabled directory. In the following command, replace example.com with the name of the domain.
    sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
  7. (Optional) For enhanced security, unlink the default site.
    sudo unlink /etc/nginx/sites-enabled/default

Configuring the MariaDB Database

The MariaDB database is ready to use since we have installed it first step. However, a new database user has to be created for our web application. It is also important to tighten application security. To finish configuring MariaDB, follow these steps.

  1. Log in to the MariaDB shell as the root user. The application displays the MariaDB prompt.
    sudo mysql -u root
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is 31
    Server version: 10.6.12-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MariaDB [(none)]
  2. Create the mydatabase database.
    CREATE DATABASE mydatabase;
  3. Use the CREATE USER command to add a new “web application” user. Provide a more secure user name and password in place of dbuser and password in the query.
    CREATE USER 'dbuser' IDENTIFIED BY 'password';
  4. Grant full rights to the new user. MariaDB should respond with Query OK after each line. Use the following SQL commands to configure the database.
    GRANT ALL ON mydatabase.* TO 'dbuser';
  5. Exit the MariaDB shell.
    exit;
  6. Use the built-in mysql_secure_installation tool to enhance the security of the database.
    sudo mysql_secure_installation
  7. No need to switch over to Unix socket authentication. No need to change the root password, so just enter (field blank) when prompted for first two questions i.e. Switch to unix_socket authentication and Change the root password?. However, answer Y to the following questions:
    Remove anonymous users?
    Disallow root login remotely?
    Remove test database and access to it?
    Reload privilege tables now?

At this point your MariaDB configuration is complete. Please check  MariaDB Server Documentation for further information about MariaDB.

Configuring PHP

PHP does not require any further configuration. However, an extra security measure can be applied. The following command ensures PHP only accepts requests for files that actually exist on the server. Otherwise, it can be tricked into executing malicious code. In the following command, use the socket for the installed release of PHP. This example demonstrates how to apply the configuration for PHP 8.1. If another release of PHP is installed, replace 8.1 with the actual release number.

sudo sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php/8.1/fpm/php.ini

Testing the LEMP Stack Installation on the Ubuntu Server

In addition to verifying the web server works properly, it is critical to make sure that the domain configuration (virtual host), PHP integration, and the MariaDB database work properly. This is the only way to confirm all components can interact together.

The easiest way to verify an Ubuntu LEMP stack installation is with a short test script. This script must be placed somewhere within the root  directory.

We will create a test php script to check the working of PHP and MariaDB/MySQL database connection. But before that let’s restart some services to make sure our last configuration changes are in effect.

  1. Restart the PHP module. The name of the module consists of php, the major and minor release of PHP, and -fpm. The following command starts the PHP 8.1 module. Replace 8.1 with the release number of the local PHP installation.
    sudo systemctl restart php8.1-fpm
  2. Reload NGINX to apply the changes.
    sudo nginx -s reload
  3. Confirm NGINX is still running properly using systemctl status.
    sudo systemctl status nginx
    nginx.service - A high performance web server and a reverse proxy server
         Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
         Active: active (running) since Sat 2023-07-29 11:46:58 UTC; 19h ago
    Note: If NGINX has inactive or status other than active (running), use the sudo nginx -t command to find configuration errors.
  4. Create a test file named phptest.php in the html directory for the domain. Set servername to localhost and ensure the username and password match the authentication details for the MariaDB web user account.
    <html>
    <head>
        <title>PHP Test</title>
    </head>
        <body>
        <?php echo '<p>Welcome to the Site!</p>';
    
        // The servername must be 'localhost'. Use the name and password of the web user account created earlier. Do not use the root password.
        $servername = "localhost";
        $username = "dbuser";
        $password = "password";
    
        // Create MySQL connection
        $conn = mysqli_connect($servername, $username, $password);
    
        // If the conn variable is empty, the connection has failed. The output for the failure case includes the error message
        if (!$conn) {
            die('<p>Connection failed: </p>' . mysqli_connect_error());
        }
        echo '<p>Connected successfully</p>';
        ?>
    </body>
    </html>
  5. Execute the test script in a web browser. In the address bar, enter the domain name followed by /phptest.php. In the following example, substitute the actual name of the domain for example.com.
    http://example.com/phptest.php
  6. If everything is installed correctly, it should display the text Welcome to the Site! and Connected successfully. If you see the Connection Failed: message, review the SQL error information to debug the issue. See the Troubleshooting section for more information.
  7. (Optional) Alternatively, curl can be used to test the php script. This method can be used if the DNS entry for the domain has not propagated yet. In the command below, replace example.com with the name of the domain, and server-ip-address with the IP address of the Linode. The output is formatted as HTML code, but it is reasonably easy to determine the outcome.
    curl -H "Host: example.com" http://<server-ip-address>/phptest.php
    <html>
    <head>
        <title>PHP Test</title>
    </head>
        <body>
        <p>Welcome to the Site!</p><p>Connected successfully</p></body>
    </html>
  8. When testing is complete, remove the test script.
    sudo rm /var/www/html/example.com/phptest.php
    

Conclusion

The Ubuntu LEMP Stack includes the operating system, NGINX web server, MariaDB relational database, and the PHP programming language. A server configured with these free and open source applications can host a modern website and support a rich programming environment. The LEMP stack elements are easy to install and work well together with little extra configuration.

After configuring the LEMP stack on Ubuntu, it is good practice to create an NGINX configuration file for the domain. Create a new database and user account on MariaDB for the website to use and install additional PHP packages for full integration. Test the new installation using a short PHP test script that connects to the database.

Leave a Reply