Home Database Install Nginx, MySQL, PHP (LEMP Stack) On Ubuntu 20.04 LTS
How To Install Nginx, MySQL, PHP (LEMP Stack) on Ubuntu 20.04 LTS

Install Nginx, MySQL, PHP (LEMP Stack) On Ubuntu 20.04 LTS

By sk
1683 Views

In our previous tutorial, we discussed how to install LAMP stack in Ubuntu 20.04 LTS server. In this tutorial, we will see how to install Nginx, MySQL, PHP (LEMP stack) on Ubuntu 20.04 LTS server edition. LEMP is the acronym of Linux, Engine-x, MariaDB/MySQL, PHP/Perl/Python.

Install Nginx, MySQL, PHP (LEMP Stack) on Ubuntu 20.04 LTS

For the purpose of this tutorial, I will be using the following test machine:

  • Operating System : Ubuntu 20.04 LTS Server
  • IP Address : 192.168.225.52/24

Let us get started.

1. Install Nginx On Ubuntu

Run the following command from the Terminal to install Nginx webserver:

$ sudo apt install nginx

After installing Nginx, check if Nginx service is running or not using command:

$ sudo systemctl status nginx

Sample output:

● 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 Fri 2020-05-29 10:13:47 UTC; 56s ago
       Docs: man:nginx(8)
   Main PID: 1349 (nginx)
      Tasks: 2 (limit: 2283)
     Memory: 4.4M
     CGroup: /system.slice/nginx.service
             ├─1349 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
             └─1350 nginx: worker process

May 29 10:13:46 ubuntuserver systemd[1]: Starting A high performance web server and a reverse proxy server...
May 29 10:13:47 ubuntuserver systemd[1]: Started A high performance web server and a reverse proxy server.

If you see an output like above, the Nginx service has been started.

In case Nginx service is not started yet, you can start it using command:

$ sudo systemctl enable nginx
$ sudo systemctl start nginx

1.1 Allow Nginx web server via UFW firewall

UFW, stands for Uncomplicated Firewall, is a program for managing a netfilter firewall designed to be easy to use. UFW is available by default in all Ubuntu versions.

By default, the Nginx web browser can’t be accessed from remote systems if you have enabled the UFW firewall in Ubuntu 20.04 LTS. You must allow the http and https ports by following the steps given below.

First, let us view which applications have installed a profile using command:

$ sudo ufw app list

Sample output:

Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH

As you can see, Nginx and OpenSSH applications have installed UFW profiles.

If you look into the “Nginx Full” profile, you will see that it enables traffic to the ports 80 and 443:

$ sudo ufw app info "Nginx Full"

Sample output:

Profile: Nginx Full
Title: Web Server (Nginx, HTTP + HTTPS)
Description: Small, but very powerful and efficient web server

Ports:
80,443/tcp

Now, run the following command to allow incoming HTTP and HTTPS traffic for this profile:

$ sudo ufw allow in "Nginx Full"

You will see an output something like below:

Rules updated
Rules updated (v6)

If you want to allow https traffic, but only http (80) traffic, run:

$ sudo ufw app info "Nginx HTTP"

Let us go ahead and run Nginx test page.

To do so, open up your Web browser and navigate to http://localhost/ or http://IP-Address/.

You will see the Nginx welcome page as shown below.

Nginx welcome page on Ubuntu

Congratulations! Nginx server is working!

2. Install MySQL On Ubuntu

To install MySQL On Ubuntu, run:

$ sudo apt install mysql-server

Verify if MySQL service is running or not using command:

$ sudo systemctl status mysql

Sample output:

● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2020-05-29 10:31:56 UTC; 51s ago
   Main PID: 2288 (mysqld)
     Status: "Server is operational"
      Tasks: 39 (limit: 2283)
     Memory: 325.6M
     CGroup: /system.slice/mysql.service
             └─2288 /usr/sbin/mysqld

May 29 10:31:49 ubuntuserver systemd[1]: Starting MySQL Community Server...
May 29 10:31:56 ubuntuserver systemd[1]: Started MySQL Community Server.

As you see in the above output, Mysql is running!

2.1 Setup database administrative user (root) password for Mysql

By default, MySQL root user password is blank. It is not recommended to use empty password for database administrative account. You need to secure your MySQL server by running the following script:

$ sudo mysql_secure_installation

You will be asked whether you'd like to setup "VALIDATE PASSWORD" component or not. This component allows the users to configure strong password for database credentials. If enabled, It will automatically check the strength of the password and enforces the users to set only those passwords which are secure enough. It is safe to leave this it disabled. However, you must use a strong and unique password for database credentials. If you don't want to enable this component, just press any key to skip the password validation part and continue the rest of the steps.

If your answer is Yes, you will be asked to choose the level of password validation.

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

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 y

The available password validations are low, medium and strong. Just enter the appropriate number (0 for low, 1 for medium and 2 for strong password) and hit ENTER key.

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: 0

Now, enter the password for MySQL root user. Please be mindful that you must use password for mysql root user depending upon the password policy you choose in the previous step. If you didn't enable the plugin, just use any strong and unique password of your choice.

Please set the password for root here.

New password:

Re-enter new password:

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

Once you entered the password twice, you will see the password strength (In our case it is 100). If it is OK for you, press Y to continue with the provided password. If not satisfied with password length, press any other key and set a strong password. I am OK with my current password, so I chose y.

For the rest of questions, just type y and hit ENTER. This will remove anonymous user, disallow root user login remotely and remove test database.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.

Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
- Dropping test database...
Success.

- Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done!

Done! We have set MySQL root user's password.

2.2 Change authentication method for MySQL root user

By default, the MySQL root user is set to authenticate using the "auth_socket" plugin starting from MySQL 5.7 and newer versions on Ubuntu. Even though it enhances the security, it will also complicate things when you access your database server using any external programs, for example phpMyAdmin. To fix this issue, you need to change authentication method from auth_socket to "caching_sha2_password" or "mysql_native_password".

As of MySQL 8.0 version, the preferred and default authentication plugin is caching_sha2_password. The caching_sha2_password authentication plugin provides more secure password encryption than the mysql_native_password plugin.

To change the authentication plugin, login to your MySQL prompt using command:

$ sudo mysql

Run the following command at the mysql prompt to find the current authentication method for all mysql user accounts:

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

Sample output:

+------------------+------------------------------------------------------------------------+-----------------------+-----------+
| user             | authentication_string                                                  | plugin                | host      |
+------------------+------------------------------------------------------------------------+-----------------------+-----------+
| debian-sys-maint | $A$005$=s%UO"�[email protected]>[email protected] | caching_sha2_password | localhost |
| mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password | localhost |
| mysql.session    | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password | localhost |
| mysql.sys        | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password | localhost |
| root             |                                                                        | auth_socket           | localhost |
+------------------+------------------------------------------------------------------------+-----------------------+-----------+
5 rows in set (0.00 sec)

find the current authentication method for all mysql user accounts in ubuntu

As you see, mysql root user uses auth_socket plugin for authentication.

To change auth_socket plugin to caching_sha2_password, run the following command at the mysql prompt. If you have enabled VALIDATE PASSWORD plugin, make sure you have used a strong password based on the current policy requirements. A strong should consists of at least 8 characters including an uppercase letter, a lowercase letter, a number and a special character.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'Password123#@!';

Replace "Password123#@!" with a strong and unique password of your choice in the above command.

Update the changes using command:

mysql> FLUSH PRIVILEGES;

Now check if the current authentication plugin is changed or not using command:

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

Sample output:

check the current authentication plugin in mysql

Good! Now the myql root user can authenticate using password to access mysql shell.

Exit from the mysql prompt:

mysql> exit

Note:

Even though caching_sha2_password plugin provides enhanced secure encryption, it has some compatibility issues with existing MySQL installations. For details, refer this link. If you encountered with any compatibility issues, you need to set "mysql_native_password" plugin as default authentication plugin.

To change to mysql_native_password plugin, run the following command at mysql prompt.

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

Update the changes using command:

mysql> FLUSH PRIVILEGES;

Now check again if the authentication method is changed or not using command:

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

Sample output:

find the current authentication method for all mysql user accounts

Exit from the mysql prompt by entering the following command:

exit

3. Install PHP On Ubuntu

To install PHP, run:

$ sudo apt-get install php-fpm php-mysql

After installing PHP, we need to secure it by doing a simple change in php.ini file.

To do so, edit php.ini file using your favorite editor:

$ sudo vi /etc/php/7.4/fpm/php.ini

Find the following line:

;cgi.fix_pathinfo=1

Uncomment it and change its value from 1 to 0 (zero).

cgi.fix_pathinfo=0

Save and close the file. Then, restart PHP-FPM service to take effect the changes.

$ sudo systemctl restart php7.4-fpm

Check PHP-FPM service is running or not using command:

$ sudo systemctl status php7.4-fpm

Sample output:

● php7.4-fpm.service - The PHP 7.4 FastCGI Process Manager
     Loaded: loaded (/lib/systemd/system/php7.4-fpm.service; enabled; vendor preset: en>
     Active: active (running) since Fri 2020-05-29 10:40:45 UTC; 11s ago
       Docs: man:php-fpm7.4(8)
    Process: 10711 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/ph>
   Main PID: 10693 (php-fpm7.4)
     Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
      Tasks: 3 (limit: 2283)
     Memory: 7.0M
     CGroup: /system.slice/php7.4-fpm.service
             ├─10693 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
             ├─10709 php-fpm: pool www
             └─10710 php-fpm: pool www

May 29 10:40:44 ubuntuserver systemd[1]: Starting The PHP 7.4 FastCGI Process Manager...
May 29 10:40:45 ubuntuserver systemd[1]: Started The PHP 7.4 FastCGI Process Manager.

3.1 Configure Nginx to use PHP-FPM

We need to configure Nginx to use PHP-FPM.

To do so, edit Nginx's default vhost (Server block) /etc/nginx/sites-available/default file:

$ sudo vi /etc/nginx/sites-available/default

Find the Server section, and set your Ubuntu server's FQDN or IP address as shown below. And also, double check if you have added the index.php line. All changes are shown in bold letters.

[...]
server {
 listen 80 default_server;
 listen [::]:80 default_server;

[...]

root /var/www/html;

 # Add index.php to the list if you are using PHP
 index index.php index.html index.htm index.nginx-debian.html;

 server_name 192.168.225.52;
[...]

Configure Nginx to use PHP-FPM

Here,

  • listen 80; -> listen for ipv4.
  • listen [::]:80 default_server ; -> listen for ipv6.
  • index.php -> Add this if you use PHP.
  • root /var/www/html; -> Nginx document root directory.
  • server_name 192.168.225.52; -> Our Ubuntu server's IP Address.

Then, scroll down a little bit and find the "#location ~ \.php$" section.

Uncomment and modify the following lines as shown below.

location ~ \.php$ {
include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
}
# deny access to .htaccess files, if Apache's document root
 # concurs with nginx's one
 #
 location ~ /\.ht {
 deny all;
 }
}

Refer the following screenshot. The changes are marked/underlined with red color.

Configure Nginx to use PHP-FPM In Ubuntu

Save and exit the file.

Pay close attention when modifying fastcgi_pass directive within the location ~ \.php$ block. You must mention the correct name file with what is actually stored in the /var/run/php directory on your server. To verify it, run:

$ ls /var/run/php/
php-fpm.sock php7.4-fpm.pid php7.4-fpm.sock

As you can see, the name of the file is php7.4-fpm.sock. Make sure you have mentioned the correct name in this directive.

Check the Nginx configuration file for any syntax errors using command:

$ sudo nginx -t

Sample output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If you don't see any errors, restart nginx service to take effect the changes.

To do so, run:

$ sudo systemctl restart nginx

Now, let us create a sample PHP file to test the PHP configuration via browser.

To do so, create a file called "info.php" under Nginx document root folder.

$ sudo vi /var/www/html/info.php

Add the following lines:

<?php
phpinfo();
?>

Save and quit the file. Restart nginx service to take effect the changes.

$ sudo systemctl restart nginx

Then, open your web browser and navigate to http://IP-address/info.php.

You will see the PHP details.

PHP-FPM Info Page

Congratulations! PHP is working!!

3.2 Install PHP modules

To improve the functionality of PHP, you can install some additional PHP modules.

To list the available PHP modules, run:

$ sudo apt-cache search php- | less

Sample output:

list all available PHP modules in Ubuntu 20.04

Use and arrows to move up and down between the result. To exit, type q.

To find the details of any particular php module, for example php-gd, run:

$ sudo apt-cache show php-gd

To install a php module run:

$ sudo apt-get install php-gd

To install all modules (not necessary though), run:

$ sudo apt-get install php*

Do not forget to restart Nginx service after installing any php module.

Congratulations! We have successfully setup LEMP stack in Ubuntu 20.04 LTS server. Start deploying websites and web applications in your new LEMP web stack.

Read Next:

Thanks for stopping by!

Help us to help you:

Have a Good day!!

You May Also Like

1 comment

RO July 4, 2020 - 2:16 am

Great!!!

Reply

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More