How to install and configure NGINX, MariaDB, PHP-FPM v7 (LEMP stack) on CentOS 7

This article is about how to install LEMP stack on your hosting. LEMP stack is a set of open source software that enables the hosting to serve dynamic web pages. LEMP stands for Linux OS, NGINX (pronounced as ENGINX), MySQL database, and PHP.

Install LEMP stack and configure it

Assuming, you already have the root or sudo access to the hosting. In the case of DigitalOcean, Vultr, Linode hosting providers, you should either have the root SSH access with the password or a private key file. In the case of Amazon EC2, generally, you will have a sudo access with the user centos and a private key file.

What are the steps we are going to cover in this article?

  1. CentOS 7 common steps before installation
  2. Install and configure NGINX web server
  3. Install and configure the MariaDB database server
  4. Install and configure PHP-FPM v7 as a server-side programming language
  5. Install PHPMyAdmin
  6. Install SSL for your domain

CentOS 7 Common Steps

First thing is first. Let’s update all the currently installed packages to make them up-to-date. The following command will do the job!

sudo yum -y update

Alternatively, you can use the following command as well, which will do the same job as the command above, with additionally removing all the obsolete packages. Running this command for the first time is okay when you are just setting up a new server. However, running this command on a server, which is already set up, could be dangerous as you might be ending up removing a package that is currently in use.

sudo yum -y upgrade

Next, install the EPEL releases, YUM utilities, and Networking tools.

sudo yum -y install perl
sudo yum -y install epel-release
sudo yum -y install yum-utils
sudo yum -y install dpkg-devel dpkg-dev
sudo yum -y install bind-utils
sudo yum -y install net-tools
sudo yum -y install zip
sudo yum -y install unzip

Additionally, enable the Remi repository. We will need it while installing the PHP version 7.2.

sudo yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum-config-manager --enable remi-php72

The following one is not a mandatory step, however, it’s always good to setup everything in the proper way. If you see the warning below, after SSH login to your server:

LC_CTYPE: cannot change locale (UTF-8)

Then, you can follow the steps below to rectify it.

sudo vi /etc/environment

Add these lines to the file, save, and exit.

LANG=en_US.utf-8
LC_ALL=en_US.utf-8

Time to install and configure NGINX web server

sudo yum -y install nginx

After the NGINX installation is complete, start the NGINX web server and enable it for the boot. Enabling a service for the boot makes sure the server gets started automatically by a boot job when the server is rebooted.

sudo systemctl start nginx
sudo systemctl enable nginx

You can check if the NGINX web server is running on port 80 by running this command below

netstat -tulpn

Next step is to make sure that the server firewall (if you are using one) is configured properly to allow HTTP (port 80) and HTTPS (port 443) publicly from the outside.

sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload

If you are not using any server firewall and rather using the hosting provider’s firewall, e.g. Vultr, DigitalOcean, Amazon AWS EC2 etc., then port 80 and 443 need to be allowed there.

Now running the server’s IP on a web browser should show you the default NGINX web page. Therefore, the web server installation part is now complete for the install LEMP stack process.

Database: Install and Configure MariaDB

In addition, we need a database server as well along with the web server in most common cases. Therefore, let’s proceed with one of the most popular databases MariaDB installation.

sudo yum -y install mariadb-server mariadb

After the MariaDB installation is complete, start the MariaDB database server and enable it for the boot.

sudo systemctl start mariadb
sudo systemctl enable mariadb

Now, the most crucial step is to secure the database server. Run the following command.

sudo mysql_secure_installation

It will ask you for the following inputs:

Enter current password for root (enter for none):
Change the root password? [Y/n]
Remove anonymous users? [Y/n]
Disallow root login remotely? [Y/n]
Remove test database and access to it? [Y/n]
Reload privilege tables now? [Y/n]

Your answers should be entered, Y (enter and confirm new root password), Y, Y, Y, Y.

Install and configure PHP-FPM v7 as a server-side programming language

Remember, during step 1, we have enabled the Remi repository for php7.2. So the following commands will install the version 7.2 of php-fpm.
sudo yum -y install php php-fpm php-mysql php-common php-opcache php-mcrypt php-cli php-curl

After the PHP installation is complete, start PHP-fpm and enable it for the boot.

sudo systemctl start php-fpm
sudo systemctl enable php-fpm

Need to do some necessary modifications to the php.ini config file.

sudo vi /etc/php.ini

Search for cgi.fix_pathinfo and uncomment the line if commented and change the value to zero.

cgi.fix_pathinfo=0

Save the file and close the editor.

sudo vi /etc/php-fpm.d/www.conf

Search and modify ‘user’ and ‘group’ from ‘apache’ to ‘nginx’.

user = nginx
group = nginx

Instead of using the server port, PHP-FPM will run under a socket file. Change the ‘listen’ value to the path ‘/run/php-fpm/php-fpm.sock’ as shown below.

listen = /run/php-fpm/php-fpm.sock

The socket file owner will be the ‘nginx’ user, and the permission mode is 660. Uncomment and change all values like this:

listen.owner = nginx
listen.group = nginx
listen.mode = 0660

Save the file and close the editor.

sudo systemctl restart php-fpm

sudo vi /etc/nginx/nginx.conf

Add these lines after the block.

location / {
}

location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

save the file and close the editor and then run the NGINX config test.

sudo nginx -t

If it shows

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

Then restart the web service.

sudo systemctl restart nginx

Else, sorry! Either need to debug by yourself or comment on your problem and I will try to answer!

cd /usr/share/nginx/html
ls -al

here you will see the default index page that is served when the IP is hit on a browser.

sudo vi info.php

Save the file and close the editor. Now, you should be able to see the phpinfo by running http://your.host.ip.address/info.php. If you have any domain ready and pointed to this IP already, let’s proceed with the vhost file creation.

sudo vi /etc/nginx/conf.d/example-domain.conf

Paste the following configuration.

server {
listen 80;
listen [::]:80 ipv6only=on;

server_name example-domain.com www.example-domain.com;

access_log /var/log/nginx/example-domain-access.log;
error_log /var/log/nginx/example-domain-error.log;

root /var/www/example-domain/public;
index index.php index.html;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

now sudo mkdir -p /var/www/example-domain/public
sudo chown nginx:nginx /var/www/example-domain -R
sudo systemctl restart nginx

Install PHPMyAdmin

This is not a mandatory step in the install LEMP stack process. However, this is required most commonly for setting up and configuring databases and DB users.

LetsEncrypt SSL Installation

sudo yum -y install certbot-nginx
sudo certbot --nginx -d example-domain.com -d www.example-domain.com

It will be asking for some inputs like below and you need to provide proper answers for those.

Please read the Terms of Service

(A)gree/(C)ancel: A

Would you be willing to share your email address with the Electronic Frontier
Foundation

(Y)es/(N)o: N

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
——————————————————————————-
1: No redirect – Make no further changes to the webserver configuration.
2: Redirect – Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you’re confident your site works on HTTPS. You can undo this
change by editing your web server’s configuration.
——————————————————————————-

You should answer 2 to redirect all requests to HTTPS. Google is strongly recommending to use secure sites.

Need to do a couple of updates to make the SSL more secure and standard.

sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

sudo vi /etc/nginx/conf.d/example-domain.conf

Find for ssl_dhparam line and replace with the following.

ssl_dhparam /etc/ssl/certs/dhparam.pem;

sudo vi /etc/letsencrypt/options-ssl-nginx.conf

Find for ssl_protocols lines and replace with the following.

ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";

Now restart the web service.

sudo systemctl restart nginx

Set a cronjob to renew the SSL certificate automatically.

sudo crontab -e

15 3 * * * /usr/bin/certbot renew –quiet

Test your site’s SSL status with SSL Labs.

Finally, clean up everything.

sudo yum clean all