Oct 10, 2023 8 min read

How to Install Linux, Nginx, MySQL, and PHP on Ubuntu 20.04

Install Linux, Nginx, MySQL, and PHP on Ubuntu20.04 with our step-by-step tutorial. LEMP is a web stack for dynamic websites & applications.

Install Linux, Nginx, MySQL, and PHP on Ubuntu 20.04
Table of Contents

Choose a different version or distribution

Introduction

Before we begin talking about how to install LEMP on Ubuntu 20.04 OS, let’s briefly understand – What is LEMP?

LEMP is a web stack for dynamic websites & applications. It consists of four key components: Linux, Nginx (pronounced "engine-x"), MySQL, and PHP. Linux provides the operating system, Nginx acts as the web server, MySQL manages the database, and PHP serves as the scripting language.

LEMP is known for its performance, scalability, and reliability, making it ideal for handling heavy traffic and dynamic content. By combining these powerful technologies, developers can create fast and efficient websites and applications that deliver a seamless user experience.

You’ll install LEMP on Ubuntu 20.04 in this tutorial. Also, we will answer some FAQs related to LEMP installation.

Advantages of LEMP

  1. Performance: LEMP offers high performance and scalability, ensuring fast loading times for websites and applications.
  2. Reliability: With its robust components, LEMP provides stability and uptime, ensuring a reliable user experience.
  3. Flexibility: LEMP supports a wide range of web applications, making it versatile and adaptable.
  4. Security: LEMP has built-in security features and can be further enhanced to protect against vulnerabilities and attacks.
  5. Cost-efficiency: LEMP is open-source and free to use, making it a cost-effective choice for hosting websites and applications.

Prerequisites

  • Ubuntu 20.04 64-bit operating system
  • A user account with sudo privileges
  • Command-line / terminal

Step 1 – Install the Nginx Web Server

1) Firstly, use the apt package-management suite to complete the necessary installations.

2) Update your server's package index and install the server.

sudo apt update
sudo apt install nginx

3) Nginx will start running upon installation.

4) After that, allow connections to Nginx. It registers itself with ufw after installation, so the procedure is rather straightforward.

5) Since there is no SSL certificate configured to allow traffic only on port 80. Do this by typing the command below:

sudo ufw allow 'Nginx HTTP'

6) Now, the change must be verified by running the following:

sudo ufw status

You will see the following output saying HTTP traffic is allowed.

Output

Status: active

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

7) Run the following command to know your server’s public IP address:

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

8) Now check which IP address is accessible, as viewed from other locations on the internet:

curl -4 icanhazip.com

9) You will be taken to Nginx's default landing page after typing the address you received in your web browser.

http://server_domain_or_IP

You must see the below image after the installation of Nginx.

Welcome Message after installing Nginx

Once this screen is visible, you can be sure that the Nginx is installed.

Step 2 - Install MySQL

1) By typing the below command, install MySQL:

sudo apt install mysql-server

2) Secondly, by typing Y, and then ENTER confirm the installation.

3) After that, run a security script that comes pre-installed with MySQL. As a result, insecure default settings and lockdowns to access your database will be removed. Run the below command to start the interactive script:

sudo mysql_secure_installation

Now, you will be asked if you want to configure the VALIDATE PASSWORD PLUGIN.

💡
If the passwords which you have set don't match the specified criteria then MySQL will reject it with an error. Leave the validation disabled and always use strong, unique passwords for database credentials.

4) Now, answer Y for yes, or anything else to continue without enabling.

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:

5) If your answer is "yes", select a level of password validation.

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

6) If you have selected 2 - the strongest level of validation, then you will get errors if you haven't added numbers, upper and lower case letters, and special characters.

7) Now, submit and confirm a root password:

Please set the password for root here.

New password:

Re-enter new password:

Similarly, press Y and hit the ENTER key at each prompt for the rest of the questions.

💡
If you got stuck on password prompts, then exit out of it and alter the root password and set new in MySQL prompt using ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; . After this relaunch secure installation and press n for change root password.

8) If you are using auth-socket plugin to access MySQL, then you can skip the further steps and jump straight to Step 3. Switch authentication method from auth_socket to mysql_native_password to use a password when connecting MySQL as root. Open MySQL prompt from your terminal:

sudo mysql

9) Check different authentication methods by running the following command:

mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;

You must see the following output:

Output
+------------------+-------------------------------------------+-----------------------+-----------+
| user             | authentication_string                     | plugin                | host      |
+------------------+-------------------------------------------+-----------------------+-----------+
| root             |                                           | auth_socket           | localhost |
| mysql.session    | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys        | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+-----------+
4 rows in set (0.00 sec)

10) Then, run the following ALTER USER command to configure the root account to authenticate with a password.

Make sure to change password to a strong password of your choosing:

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

11)After that, put new changes into effect by running FLUSH PRIVILEGES:

mysql> FLUSH PRIVILEGES;

12) Now, using the auth_socket plugin, check authentication methods employed by each of your users to confirm that root no longer authenticates:

mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;

You must see the following output:

Output
+------------------+-------------------------------------------+-----------------------+-----------+
| user             | authentication_string                     | plugin                | host      |
+------------------+-------------------------------------------+-----------------------+-----------+
| root             | *3636DACC8616D997782ADD0839F92C1571D6D78F | mysql_native_password | localhost |
| mysql.session    | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys        | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+-----------+
4 rows in set (0.00 sec)

13) Finally, exit the MySQL shell:

mysql> exit
💡
After configuring your root MySQL user to authenticate with a password, you’ll no longer be able to access MySQL with the sudo mysql command used previously. Instead, you must run the following: mysql -u root -p . After entering the password, you will see the MySQL prompt.

Step 3 – Install PHP and Configure Nginx to Use the PHP Processor

Now, you have Nginx that will serve the pages and MySQL that will store as well as manage your data. Now we need something that can generate dynamic data.

1) Firstly, install php-fpm, which stands for “fastCGI process manager” as PHP requests to this software for processing

💡
You will have to add Ubuntu's universe repository based on your cloud provider. It includes free and open-source software maintained by the Ubuntu Community. Before installing php-fpm type: sudo add-apt-repository universe

2) Secondly, allow PHP to communicate with your database backend by installing the php-fpm module along with an additional helper package, php-mysql using the following command:

sudo apt install php-fpm php-mysql

3) Now, to tell Nginx to use the PHP processor for dynamic content, you must make a few configuration changes.

Do this by opening a new server block configuration file within the /etc/nginx/sites-available/ directory:

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

4) After that, include the following content which is slightly modified from the default server block configuration file to your new server block configuration file:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name example.com;

        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;
        }
}

Now, save and close the file.

5) Meanwhile, activate your new server block by creating a symbolic link from your new server block configuration file (in the /etc/nginx/sites-available/ directory) to the /etc/nginx/sites-enabled/ directory:

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

6) Now, un-link the default configuration file from the /sites-enabled/ directory:

sudo unlink /etc/nginx/sites-enabled/default
💡
If you ever need to restore the default configuration, you can do so by recreating the symbolic link, like this:
sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/

7) Now, it's time to test your configuration file for syntax errors:

sudo nginx -t

Continue further after zero errors.

8) Finally, reload Nginx to make the required changes:

sudo systemctl reload nginx

Step 4 – Create a PHP File to Test Configuration

1) Firstly, test your LEMP stack to validate that Nginx can correctly give .php files to the PHP processor.

  • Begin by creating a test PHP file called info.php in your document root:
sudo nano /var/www/html/info.php

2) Secondly, add the following text (which is valid PHP code) inside the blank file which is opened:

<?php
phpinfo();

Save and close the file after you complete this process.

3) Test this script by accessing your server’s domain name or IP address, followed by the script name, which in this case is info.php in a web browser:

http://server_domain_or_IP/info.php

You must see a page similar to this:

A summary of PHP installation on the server

Use the information displayed on this page for debugging and to ensure that your settings are being applied correctly.

4) Finally, remove the file you created, as it contains sensitive information about your PHP environment and your Ubuntu server. You can use rm to do so:

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

Now, you have a fully configured and functioning LEMP stack on your Ubuntu 20.04 server.

FAQs to Install LEMP on Ubuntu 20.04

How do I start or stop Nginx service? 

Use the commands sudo systemctl start nginx to start the service and sudo systemctl stop nginx to stop it. You can also use restart instead of start to restart the service.

How do I start or stop MySQL service? 

Use the commands sudo systemctl start mysql to start the service and sudo systemctl stop mysql to stop it. Use restart instead of start to restart the service.

How do I check if Nginx is running? 

Execute sudo systemctl status nginx to check the status of Nginx. If it's running, you will see an active (running) message.

How do I check if MySQL is running? 

Run sudo systemctl status mysql to check the status of MySQL. An active (running) message indicates that it's running properly.

Where are the Nginx configuration files located? 

The main Nginx configuration file can be found at /etc/nginx/nginx.conf. Additional configurations can be stored in the /etc/nginx/conf.d/ directory.

Where can I place my PHP files in Nginx?

 By default, Nginx serves files from the /var/www/html/ directory. You can place your PHP files there or configure additional locations in Nginx's configuration files.

How do I enable SSL/HTTPS for my website hosted on LEMP? 

How do I enable SSL/HTTPS for my website hosted on LEMP? A: Obtain an SSL certificate, configure Nginx to use the certificate, and redirect HTTP traffic to HTTPS. Tools like Let's Encrypt can help automate this process.

Conclusion

We hope this detailed guide helped you understand how to install LEMP on your Ubuntu 20.04 machine.

If you have any queries, please leave a comment below and we’ll be happy to respond to them for sure.

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to DevOps Tutorials - VegaStack.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.