December 3, 2021
How to install LEMP Stacke on CentOS 8

How To Install LEMP Stack (Linux, Nginx, MariaDB, PHP) on CentOS 8

On this article we will learn how to install LEMP Stack on CentOS 8 operating system, LEMP is an acronym LEMP is an acronym for Linux, Nginx (pronounced as Engine X), MariaDB/MySQL and PHP.

Introduction

LEMP is a software stack consisting of a set of free and open-source tools for developing dynamic websites and application. LEMP is an acronym for Linux, Nginx (pronounced as Engine X), MariaDB/MySQL and PHP. On this term, Linux operating system where the applications is running, Nginx (pronounced like “Engine-X”) as a web server, and M refering to MariaDB/My SQL as database layer (MariaDB became a widely accepted alternative to MySQL) and P referring to PHP as the dynamic processing tools written in PHP language. On this article we will learn how to install LEMP (Linux, Nginx, MariaDB, PHP) stack on CentOS 8.



LEMP Stack Installation On CentOS 8

Before we start the LEMP stack installation process on CentOS 8, there are prerequisites that must be met, namely:

  • A CentOS 8 Server with sufficient disk space
  • An account with sudo or root access to run privileged commands
  • Internet access for downloading any required packages

LEMP Installation Steps:

  1. Installing the Nginx Web Server
  2. Installing MariaDB
  3. Installing PHP
  4. Testing PHP with Nginx Webserver

1. Installing Nginx Webserver

At the first stage, we will update our CentOS 8 system. By updating the system, we will have our server with all the latest stable releases from CentOS Repository. This task can be done by submitting command line : sudo dnf update.

[ramans@diginetapp01 ~]$ sudo dnf update
[sudo] password for ramans: 
Last metadata expiration check: 0:09:22 ago on Sat 07 Aug 2021 01:04:33 AM PDT.
Dependencies resolved.
===============================================================================================
 Package                           Arch   Version                              Repo       Size
===============================================================================================
Installing:
 centos-linux-release              noarch 8.4-1.2105.el8                       BaseOS     22 k
     replacing  centos-release.x86_64 8.2-2.2004.0.1.el8
     replacing  centos-repos.x86_64 8.2-2.2004.0.1.el8
 kernel                            x86_64 4.18.0-305.10.2.el8_4                BaseOS    5.9 M
 kernel-core                       x86_64 4.18.0-305.10.2.el8_4                BaseOS     36 M
 kernel-devel                      x86_64 4.18.0-305.10.2.el8_4                BaseOS     18 M
 kernel-modules                    x86_64 4.18.0-305.10.2.el8_4                BaseOS     28 M
Upgrading:
 NetworkManager                    x86_64 1:1.30.0-9.el8_4                     BaseOS    2.6 M
 NetworkManager-adsl               x86_64 1:1.30.0-9.el8_4                     BaseOS    141 k
 NetworkManager-libnm              x86_64 1:1.30.0-9.el8_4                     BaseOS    1.8 M
 NetworkManager-team               x86_64 1:1.30.0-9.el8_4                     BaseOS    145 k
 NetworkManager-tui                x86_64 1:1.30.0-9.el8_4                     BaseOS    328 k
 NetworkManager-wifi               x86_64 1:1.30.0-9.el8_4                     BaseOS    186 k
 PackageKit                        x86_64 1.1.12-6.el8                         AppStream 599 k
 PackageKit-command-not-found      x86_64 1.1.12-6.el8                         AppStream  27 k

Installing Nginx web server

After we updating CentOS 8 system, we will install Nginx webserver on this system, by submitting command line : sudo dnf install nginx.

[ramans@diginetapp01 ~]$ sudo dnf install nginx
[sudo] password for ramans: 
CentOS Linux 8 - AppStream                                              1.2 MB/s | 8.4 MB     00:06    
CentOS Linux 8 - BaseOS                                                 205 kB/s | 4.5 MB     00:22    
Dependencies resolved.
========================================================================================================
 Package                        Arch      Version                                    Repository    Size
========================================================================================================
Installing:
 nginx                          x86_64    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream    570 k
Installing dependencies:
 nginx-all-modules              noarch    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream     23 k
 nginx-filesystem               noarch    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream     24 k
 nginx-mod-http-image-filter    x86_64    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream     35 k
 nginx-mod-http-perl            x86_64    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream     45 k
 nginx-mod-http-xslt-filter     x86_64    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream     33 k
 nginx-mod-mail                 x86_64    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream     64 k
 nginx-mod-stream               x86_64    1:1.14.1-9.module_el8.0.0+184+e34fea82     appstream     85 k
Enabling module streams:
 nginx                                    1.14                                                         

Transaction Summary
========================================================================================================
Install  8 Packages

Total download size: 881 k
Installed size: 2.0 M
Is this ok [y/N]: y
Downloading Packages:
(1/8): nginx-filesystem-1.14.1-9.module_el8.0.0+184+e34fea82.noarch.rpm 153 kB/s |  24 kB     00:00    
(2/8): nginx-all-modules-1.14.1-9.module_el8.0.0+184+e34fea82.noarch.rp 118 kB/s |  23 kB     00:00    
Install Nginx pacakge on CentOS 8
Install Nginx pacakge on CentOS 8

After installing Nginx, then we will enable, starting it up on the system and checking it status. These taske is done by submitting the command line : sudo systemctl enable nginx, sudo systemctl start nginx, sudo systemctl status nginx.

[ramans@diginetapp01 ~]$ sudo systemctl start nginx
[ramans@diginetapp01 ~]$ sudo systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2021-08-07 01:38:10 PDT; 5s ago
  Process: 103123 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 103121 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 103119 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 103124 (nginx)
    Tasks: 5 (limit: 11312)
   Memory: 15.4M
   CGroup: /system.slice/nginx.service
           ├─103124 nginx: master process /usr/sbin/nginx
           ├─103125 nginx: worker process
           ├─103126 nginx: worker process
           ├─103127 nginx: worker process
           └─103128 nginx: worker process

Aug 07 01:38:10 diginetapp01 systemd[1]: Starting The nginx HTTP and reverse proxy server...
Aug 07 01:38:10 diginetapp01 nginx[103121]: nginx: the configuration file /etc/nginx/nginx.conf syntax >
Aug 07 01:38:10 diginetapp01 nginx[103121]: nginx: configuration file /etc/nginx/nginx.conf test is suc>
Aug 07 01:38:10 diginetapp01 systemd[1]: Started The nginx HTTP and reverse proxy server.
Startup Nginx on CentOS 8
Startup Nginx on CentOS 8

In case we have deployed firewall on the system, then we have to enable the connection through the firewall. To permanently enable the HTTP connection over firewall we can submit the command line : sudo firewall-cmd --permanent --add-service=http. Then to verify the changes, we will verify it by submitting command line : sudo firewall-cmd --permanent --list-all as shown below.

[ramans@diginetapp01 ~]$ sudo firewall-cmd --permanent --add-service=http
success
[ramans@diginetapp01 ~]$ sudo firewall-cmd --permanent --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: cockpit dhcpv6-client http ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[ramans@diginetapp01 ~]$ sudo firewall-cmd --reload
success

Then to take effect of updating firewall configuration we will reload it by cubmitting command line : sudo firewall-cmd --reload.

  rich rules: 
[ramans@diginetapp01 ~]$ sudo firewall-cmd --reload
success
Verify firewall
Verify firewall

After all are set, the we will verity the Nginx installation by using web broswser then hit the url http://localhost as shown below.

Nginx web server are ready
Nginx web server are ready

2. Installing MariaDB

Until this stage, we have a web server up and running, then we need to install a database system to store and manage data for out site. On this section, we will install MariaDB as our database system on LEMP Stack. The installation are as described below. We will use the command line : sudo dnf install mariadb-server to install MariaDB database server on our CentOS 8 system.

[ramans@diginetapp01 ~]$ sudo dnf install mariadb-server
Last metadata expiration check: 0:07:05 ago on Sat 07 Aug 2021 01:36:25 AM PDT.
Dependencies resolved.
========================================================================================================
 Package                       Arch      Version                                     Repository    Size
========================================================================================================
Installing:
 mariadb-server                x86_64    3:10.3.28-1.module_el8.3.0+757+d382997d     appstream     16 M
Installing dependencies:
 mariadb                       x86_64    3:10.3.28-1.module_el8.3.0+757+d382997d     appstream    6.0 M
 mariadb-common                x86_64    3:10.3.28-1.module_el8.3.0+757+d382997d     appstream     64 k
 mariadb-connector-c           x86_64    3.1.11-2.el8_3                              appstream    200 k
 mariadb-connector-c-config    noarch    3.1.11-2.el8_3                              appstream     15 k
 mariadb-errmsg                x86_64    3:10.3.28-1.module_el8.3.0+757+d382997d     appstream    234 k
 perl-DBD-MySQL                x86_64    4.046-3.module_el8.1.0+203+e45423dc         appstream    156 k
 perl-DBI                      x86_64    1.641-3.module_el8.1.0+199+8f0a6bbd         appstream    740 k
 perl-Math-BigInt              noarch    1:1.9998.11-7.el8                           baseos       196 k
 perl-Math-Complex             noarch    1.59-419.el8                                baseos       108 k
Installing weak dependencies:
 mariadb-backup                x86_64    3:10.3.28-1.module_el8.3.0+757+d382997d     appstream    6.1 M
 mariadb-gssapi-server         x86_64    3:10.3.28-1.module_el8.3.0+757+d382997d     appstream     51 k
 mariadb-server-utils          x86_64    3:10.3.28-1.module_el8.3.0+757+d382997d     appstream    1.1 M
Enabling module streams:
 mariadb                                 10.3                                                          
 perl-DBD-MySQL                          4.046                                                         
 perl-DBI                                1.641                                                         

Transaction Summary
========================================================================================================
Install  13 Packages

Total download size: 31 M
Installed size: 156 M
Is this ok [y/N]: y



Install MariaDB on CentOS 8
Install MariaDB on CentOS 8

After installation was completed done, then we will start its service up and querying its status by submitting command line : sudo systemctl start mariadb and sudo systemctl status mariadb.

[ramans@diginetapp01 ~]$ sudo systemctl start mariadb
[ramans@diginetapp01 ~]$ sudo systemctl status mariadb
● mariadb.service - MariaDB 10.3 database server
   Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2021-08-07 01:45:56 PDT; 8s ago
     Docs: man:mysqld(8)
           https://mariadb.com/kb/en/library/systemd/
  Process: 105048 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
  Process: 104911 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mariadb.service (code=exited, status=0>
  Process: 104886 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
 Main PID: 105017 (mysqld)
   Status: "Taking your SQL requests now..."
    Tasks: 30 (limit: 11312)
   Memory: 102.7M
   CGroup: /system.slice/mariadb.service
           └─105017 /usr/libexec/mysqld --basedir=/usr

Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: See the MariaDB Knowledgebase at http://mari>
Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: MySQL manual for more instructions.
Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: Please report any problems at http://mariadb>
Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: The latest information about MariaDB is avai>
Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: You can find additional information about th>
Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: http://dev.mysql.com
Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: Consider joining MariaDB's strong and vibran>
Aug 07 01:45:56 diginetapp01 mysql-prepare-db-dir[104911]: https://mariadb.org/get-involved/
Aug 07 01:45:56 diginetapp01 mysqld[105017]: 2021-08-07  1:45:56 0 [Note] /usr/libexec/mysqld (mysqld 1>
Aug 07 01:45:56 diginetapp01 systemd[1]: Started MariaDB 10.3 database server.

and then improve its security level by submitting a certain shell scripting. On this section we will execute the command lines : sudo mysql_secure_installation.

[ramans@diginetapp01 ~]$ sudo mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] 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? [Y/n] Y
 ... Success!

By default, MariaDB 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? [Y/n] 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? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
Securing MariaDB database
Securing MariaDB database

After MariaDB installation was completed done, we will try to login to database by using root user, by using command line : mysql -u root -p.

[ramans@diginetapp01 ~]$ mysql -u root -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 36
Server version: 10.3.28-MariaDB MariaDB Server

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)]> quit

3. Installing PHP

The last tools on LEMP Stack is PHP, a scripting web programming language which is widely used for the development of dynamic web pages. On this section we will install PHP from CentOS 8 repository. We will use the latest PHP which is available on existing repository. Firstly, we will list the PHP version by submitting command line : sudo dnf module list php.

[ramans@diginetapp01 ~]$ sudo dnf module list php
Last metadata expiration check: 0:25:20 ago on Sat 07 Aug 2021 01:36:25 AM PDT.
CentOS Linux 8 - AppStream
Name            Stream             Profiles                             Summary                         
php             7.2 [d]            common [d], devel, minimal           PHP scripting language          
php             7.3                common [d], devel, minimal           PHP scripting language          
php             7.4                common [d], devel, minimal           PHP scripting language          

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
PHP Module lists
PHP Module lists

We noticed, if current PHP version to be used is version 7.2, and we will use PHP version 7.4. So, for this purpose will change the PHP version 7.4 to be enable bu submitting command line : sudo dnf module enable php:remi-7.4.

[ramans@diginetapp01 ~]$ sudo dnf module enable php:remi-7.4
Last metadata expiration check: 0:26:39 ago on Sat 07 Aug 2021 01:36:25 AM PDT.
Error: Problems in request:
missing groups or modules: php:remi-7.4
[ramans@diginetapp01 ~]$ sudo dnf module enable php:7.4
Last metadata expiration check: 0:26:50 ago on Sat 07 Aug 2021 01:36:25 AM PDT.
Dependencies resolved.
========================================================================================================
 Package                 Architecture           Version                   Repository               Size
========================================================================================================
Enabling module streams:
 httpd                                          2.4                                                    
 php                                            7.4                                                    

Transaction Summary
========================================================================================================

Is this ok [y/N]: y
Complete!

After all are set, then we will install PHP 7.4 by submitting command line : sudo dnf install php-fpm php-mysqlnd.

[ramans@diginetapp01 ~]$ sudo dnf install php-fpm php-mysqlnd
Last metadata expiration check: 0:29:09 ago on Sat 07 Aug 2021 01:36:25 AM PDT.
Dependencies resolved.
========================================================================================================
 Package                Architecture Version                                      Repository       Size
========================================================================================================
Installing:
 php-fpm                x86_64       7.4.6-4.module_el8.3.0+434+2ab5050a          appstream       1.6 M
 php-mysqlnd            x86_64       7.4.6-4.module_el8.3.0+434+2ab5050a          appstream       192 k
Installing dependencies:
 httpd-filesystem       noarch       2.4.37-39.module_el8.4.0+778+c970deab        appstream        38 k
 php-common             x86_64       7.4.6-4.module_el8.3.0+434+2ab5050a          appstream       696 k
 php-pdo                x86_64       7.4.6-4.module_el8.3.0+434+2ab5050a          appstream       123 k

Transaction Summary
========================================================================================================
Install  5 Packages

Total download size: 2.6 M
Installed size: 14 M
Is this ok [y/N]: y
Downloading Packages:
(1/5): httpd-filesystem-2.4.37-39.module_el8.4.0+778+c970deab.noarch.rp 158 kB/s |  38 kB     00:00    
(2/5): php-mysqlnd-7.4.6-4.module_el8.3.0+434+2ab5050a.x86_64.rpm       367 kB/s | 192 kB     00:00    
(3/5): php-pdo-7.4.6-4.module_el8.3.0+434+2ab5050a.x86_64.rpm           602 kB/s | 123 kB     00:00    
(4/5): php-common-7.4.6-4.module_el8.3.0+434+2ab5050a.x86_64.rpm        600 kB/s | 696 kB     00:01    
(5/5): php-fpm-7.4.6-4.module_el8.3.0+434+2ab5050a.x86_64.rpm           991 kB/s | 1.6 MB     00:01   



Install PHP 7.4 on CentOS 8
Install PHP 7.4 on CentOS 8

Before starting php-fhm service, we will modify /etc/php-fpm.d/www.conf file to update the user nginx from apache.

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx

Then we (re)start the php-fpm and nginx service, by submitting command line : sudo systemctl start php-fpm and sudo systemctl start nginx.

[ramans@diginetapp01 ~]$ sudo vi /etc/php-fpm.d/www.conf
[ramans@diginetapp01 ~]$ sudo systemctl start php-fpm
[ramans@diginetapp01 ~]$ sudo systemctl start nginx
[ramans@diginetapp01 ~]$ sudo systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
   Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2021-08-07 02:11:34 PDT; 19s ago
 Main PID: 106302 (php-fpm)
   Status: "Processes active: 0, idle: 5, Requests: 0, slow: 0, Traffic: 0req/sec"
    Tasks: 6 (limit: 11312)
   Memory: 20.0M
   CGroup: /system.slice/php-fpm.service
           ├─106302 php-fpm: master process (/etc/php-fpm.conf)
           ├─106303 php-fpm: pool www
           ├─106304 php-fpm: pool www
           ├─106305 php-fpm: pool www
           ├─106306 php-fpm: pool www
           └─106307 php-fpm: pool www

Aug 07 02:11:33 diginetapp01 systemd[1]: Starting The PHP FastCGI Process Manager...
Aug 07 02:11:34 diginetapp01 systemd[1]: Started The PHP FastCGI Process Manager.
[ramans@diginetapp01 ~]$ sudo systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/nginx.service.d
           └─php-fpm.conf
   Active: active (running) since Sat 2021-08-07 01:38:10 PDT; 33min ago
 Main PID: 103124 (nginx)
    Tasks: 5 (limit: 11312)
   Memory: 7.8M
   CGroup: /system.slice/nginx.service
           ├─103124 nginx: master process /usr/sbin/nginx
           ├─103125 nginx: worker process
           ├─103126 nginx: worker process
           ├─103127 nginx: worker process
           └─103128 nginx: worker process

Aug 07 01:38:10 diginetapp01 systemd[1]: Starting The nginx HTTP and reverse proxy server...
Aug 07 01:38:10 diginetapp01 nginx[103121]: nginx: the configuration file /etc/nginx/nginx.conf syntax >
Aug 07 01:38:10 diginetapp01 nginx[103121]: nginx: configuration file /etc/nginx/nginx.conf test is suc>
Aug 07 01:38:10 diginetapp01 systemd[1]: Started The nginx HTTP and reverse proxy server.
Starting php-pfm and nginx services
Starting php-pfm and nginx services

4. Testing PHP With Nginx Webserver

The last step on deploying LEMP Stack on CentOS 8 is to test the PHP with Nginx, whether running smoothly or not. On this example we will test PHP-FPM by creating a PHP file called info.php inside /usr/share/nginx/html directory with content as shown below:

<?php

phpinfo();

After all are set, then we will use browser and hit the url to http://localhost/info.php or http://<hostname_or_ipaddress>/php.info.php.

We will see information about the version of PHP which are running or our web server. As shown above, if we are using PHP version 7.4.6.

Conclusion

So far, on this article we have learnt how to install LEMP (Linux, Xningx, MariaDB, PHP) stack on CentOS 8. I hope this article is useful for those who need it and can be developed again to create dynamic and good web-based applications.

Share this article via :

Leave a Reply

Your email address will not be published. Required fields are marked *