How-to install & configure LEMP (Linux, Nginx, MariaDB/MySQL and PHP-FPM) on a CentOS 7 VPS

How-to install & configure LEMP (Linux, Nginx, MariaDB/MySQL and PHP-FPM) on a CentOS 7 VPS

In this tutorial we will explain How-to install & configure LEMP (Linux, Nginx, MariaDB/MySQL and PHP-FPM) on a CentOS 7 VPS.

WHAT IS LEMP?

LEMP is an archetypal model of web service solution stacks, named as an acronym of the names of its original four components: the Linux operating system, the Nginx HTTP Server, the MySQL/MariaDB relational database management system (RDBMS), and the PHP programming language.


ACCESS YOUR CENTOS 7 VPS

You will have to access your virtual server via SSH in order to install and configure the LEMP stack. You can follow our guide on how to SSH to a linux vps server.


UPDATE YOUR CENTOS 7 VPS

Next thing to do is to make sure your virtual server is fully up-to-date. A CentOS 7 VPS can be updated via its package manager known as yum. Run the following command to perform the update:

yum update

INSTALL VIM AND ENABLE EPEL

Install the vim editor if it’s not already installed on the system and enable the EPEL repository by running:

if ! type -path "vim" > /dev/null 2>&1; then yum install vim -y; fi
yum install epel-release

INSTALL MARIADB DATABASE SERVER

MariaDB is an enhanced, drop-in replacement for MySQL. It is the default database server in CentOS 7 / RedHat and can be installed on the virtual server using yum.

yum install mariadb mariadb-server

once MariaDB is installed, restart it using systemctl

systemctl restart mariadb
systemctl status mariadb

next, it is recommended to run MySQL/MariaDB post installation script mysql_secure_installation as in:

mysql_secure_installation

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

finally, edit /etc/my.cnf.d/server.cnf and add bind-address = 127.0.0.1 within the [mysqld] block:

vim +/^[mysqld /etc/my.cnf.d/server.cnf

[mysqld]
bind-address = 127.0.0.1

restart the database server using systemctl for the changes to take effect:

systemctl restart mariadb
systemctl status mariadb

verify MariaDB is listening on localhost only:

ss -tnlp | grep 3306
LISTEN  0  0   127.0.0.1:3306  *:* users:(("mysqld",1159,14))

INSTALL NGINX HTTP SERVER

Nginx is an open source reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer, HTTP cache, and a web server (origin server). It is event-based driven and asynchronous which means it uses less resources and can handle much more load and concurrent requests.

Anyway, it can be installed on the virtual server using yum:

yum install nginx

change to /etc/nginx directory and backup your original Nginx configuration file

cd /etc/nginx
cp nginx.conf{,.bak}

Now edit /etc/nginx.conf and make sure it looks like the following:

vim nginx.conf
	
user  nginx;
worker_processes  2;

error_log   /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

pid        /run/nginx.pid;

events {
        worker_connections  1024;
        use epoll;
}

# set open fd limit to 30000
worker_rlimit_nofile 30000;

http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                          '$status $body_bytes_sent "$http_referer" '
                                          '"$http_user_agent" "$http_x_forwarded_for"';

        #access_log  /var/log/nginx/access.log  main;

        sendfile        on;

        keepalive_timeout  30;
        server_tokens off;

        connection_pool_size 256;
        client_header_buffer_size 1k;
        large_client_header_buffers 4 2k;
        request_pool_size 4k;

        output_buffers 1 32k;
        postpone_output 1460;

        types_hash_max_size 2048;
        server_names_hash_bucket_size 64;

        gzip on;
        gzip_disable "MSIE [1-6]\.(?!.*SV1)";
        gzip_http_version 1.1;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;

        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";

        # include vhosts from sites-enabled/
        include /etc/nginx/sites-enabled/*.conf;

        # include configs from conf.d/*.conf
        include /etc/nginx/conf.d/*.conf;
}

You can edit the configuration to suit your needs, but in general, you would only have to tune the worker_processes option which is determined by the number of the CPUs your virtual server has.

The following command will display the number of CPUs on your CentOS VPS:

grep -c 'model name' /proc/cpuinfo

Since we’re including configuration files from /etc/nginx/sites-enabled and /etc/nginx/conf.d, we will need to create some additional directories which will held the virtual server block configurations:

mkdir /etc/nginx/{sites-available,sites-enabled}

DEFAULT NGINX VHOST

Set-up the default Nginx vhost in /etc/nginx/sites-available/default.conf. This means that any domains which are pointed/resolving to your virtual server IP address and are not yet configured, will hit this server block (vhost)

vim /etc/nginx/sites-available/default.conf

server {
    listen       80 default_server;
    server_name  _;
    root   /var/www/html/default;
    location / {
        index  index.html index.htm;
    }
    error_page  404              /404.html;
    location = /404.html {
        root   /var/www/html/default;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /var/www/html/default;
    }
}

create the document root directory for the default Nginx vhost and set-up some html files:

mkdir -p /var/www/html/default
cat << EOF > /var/www/html/default/index.html
<!DOCTYPE html>
<html lang="en">
<head>
        <title>Default Index Page</title>
</head>
<body style="background:#000;color:#fff;">
        <div style="color:#fff;width:100%;">
                <h1 align="center"><a href="https://vpsineu.com/managed-vps-hosting.html">Fully Managed LEMP VPS Hosting by VPSinEU.com</a></h1>
        </div>
</body>
</html>
EOF
cat << EOF > /var/www/html/default/404.html
<!DOCTYPE html>
<html lang="en">
<head>
        <title>Default 404 Page</title>
</head>
<body style="background:#000;color:#fff;">
        <div style="color:#fff;width:100%;">
                        <h1 align="center">HTTP 404 Not Found</h1>
                <h2 align="center"><a href="https://vpsineu.com/managed-vps-hosting.html">VPS Hosting by VPSinEU.com</a></h2>
        </div>
</body>
</html>
EOF
cat << EOF > /var/www/html/default/50x.html
<!DOCTYPE html>
<html lang="en">
<head>
        <title>Default 50x Page</title>
</head>
<body style="background:#000;color:#fff;">
        <div style="color:#fff;width:100%;">
                        <h1 align="center">Server Error</h1>
                <h2 align="center"><a href="https://vpsineu.com/managed-vps-hosting.html">VPS Hosting by VPSinEU.com</a></h2>
        </div>
</body>
</html>
EOF

WORDPRESS NGINX VHOST

vim /etc/nginx/sites-available/wordpress-vps-hosting.conf

server {
    listen 80;
    server_name wordpress-vps-hosting.com www.wordpress-vps-hosting.com;

    client_max_body_size 5m;
    client_body_timeout 60;

    access_log /var/log/nginx/wordpress-vps-hosting.log;
    error_log /var/log/nginx/wordpress-vps-hosting-error error;

    root /var/www/html/wordpress-vps-hosting;
    index  index.html index.php;

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

    error_page 403 =404;
    location ~ /\. { access_log off; log_not_found off; deny all; }
    location ~ ~$ { access_log off; log_not_found off; deny all; }
    location ~* wp-admin/includes { deny all; }
    location ~* wp-includes/theme-compat/ { deny all; }
    location ~* wp-includes/js/tinymce/langs/.*\.php { deny all; }
    location /wp-includes/ { internal; }
    #location ~* wp-config.php { deny all; }
    location ~* ^/wp-content/uploads/.*.(html|htm|shtml|php)$ {
        types { }
        default_type text/plain;
    }
    #  location ~* wp-admin {
    #      allow ;
    #      allow 127.0.0.1;
    #      deny all;
    #  }

    location = /robots.txt { access_log off; log_not_found off; }
    location = /favicon.ico { access_log off; log_not_found off; }

    location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ { access_log off; expires max; }
    location ~* \.(woff|svg)$ { access_log off; log_not_found off; expires 30d; }
    location ~* \.(js)$ { access_log off; log_not_found off; expires 7d; }

    location ~ \.php?$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors on;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_hide_header X-Powered-By;
        #fastcgi_pass 127.0.0.1:9001;
        fastcgi_pass unix:/var/run/main-php.socket;
    }
} 

Enable the newly created Nginx server blocks using the following:

cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/default.conf
ln -s /etc/nginx/sites-available/wordpress-vps-hosting.conf

Test Nginx configuration file and restart the webserver for the changes to take effect:

nginx -t
systemctl restart nginx
systemctl status nginx

INSTALL PHP-FPM

Install PHP support on the CentOS 7 VPS using yum

yum install php-fpm php-mysql php-mcrypt

also, install any other PHP module that your application requires. The list is shown below and you can always use yum search php- in the command line to get the list of available PHP modules on your CentOS 7 VPS:

php-bcmath - A module for PHP applications for using the bcmath library
php-cli - Command-line interface for PHP
php-common - Common files for PHP
php-dba - A database abstraction layer module for PHP applications
php-devel - Files needed for building PHP extensions
php-embedded - PHP library for embedding in applications
php-enchant - Enchant spelling extension for PHP applications
php-fpm - PHP FastCGI Process Manager
php-gd - A module for PHP applications for using the gd graphics library
php-imap - A module for PHP applications that use IMAP
php-intl - Internationalization extension for PHP applications
php-ldap - A module for PHP applications that use LDAP
php-mbstring - A module for PHP applications which need multi-byte string handling
php-mcrypt - Standard PHP module provides mcrypt library support
php-mysql - A module for PHP applications that use MySQL databases
php-mysqlnd - A module for PHP applications that use MySQL databases
php-odbc - A module for PHP applications that use ODBC databases
php-pdo - A database access abstraction module for PHP applications
php-pear.noarch - PHP Extension and Application Repository framework
php-pecl-memcache - Extension to work with the Memcached caching daemon
php-pgsql - A PostgreSQL database module for PHP
php-process - Modules for PHP script using system process interfaces
php-pspell - A module for PHP applications for using pspell interfaces
php-recode - A module for PHP applications for using the recode library
php-snmp - A module for PHP applications that query SNMP-managed devices
php-soap - A module for PHP applications that use the SOAP protocol
php-xml - A module for PHP applications which use XML
php-xmlrpc - A module for PHP applications which use the XML-RPC protocol

CONFIGURE PHP

Edit /etc/php.ini and change/set the following parameters:

cgi.fix_pathinfo=0
date.timezone = Europe/Amsterdam
expose_php = Off

CONFIGURE PHP-FPM

Edit /etc/php-fpm.conf and change/set the following parameters:

emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10

CONFIGURE PHP-FPM POOLS

cd /etc/php-fpm.d/
mv www.conf{,.orig}
vim www.conf

[MAIN]
;listen = 127.0.0.1:9000
listen = /var/run/main-php.socket
listen.mode = 0666
user = nginx
group = nginx
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/php.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 7
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 7
pm.max_requests = 400
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
php_admin_value[error_log] = /var/log/php-fpm/php-error.log
php_admin_flag[log_errors] = on

ENABLE AND RESTART SERVICES

nginx -t
systemctl restart nginx
systemctl status nginx
systemctl restart mariadb
systemctl status mariadb
systemctl restart php-fpm
systemctl status php-fpm
systemctl enable nginx mariadb php-fpm

If you’re one of our Linux VPS Hosting customers we can help you install and configure the LEMP stack on your virtual server for you free of charge. Just contact us and some of our experts will complete your request immediately.