Install CentOS8 + NGINX + PHP-FPM + MariaDB + Google PageSpeed + Let’s Encrypt

This tutorial will help you to configure a web server with CentOS8, NGINX, PHP-FPM, MariaDB, Google PageSpeed and Let’s Encrypt.

The installation will be done with the latest stable versions available at this moment. The packages are from official repositories if developers have them. All commands are executed as root. If you use a user without root rights, add sudo in front of each command.

The most recent stable versions at the moment of writing/updating the article:

CentOS 8.0
Nginx 1.16.0 stable
PHP 7.3.10
MariaDB 10.4.8
Google PageSpeed Module 1.16.0
Certbot 0.39.0 (for Let's Encrypt) 

Follow step by step the below instructions and you’ll get a functional server with above software specifications.

After the initial install of CentOS, check if exists updates for the operating system.

# dnf update -y

First of all secure the server (with firewall). Also, you need to allow the access for HTTP and HTTPS protocols.

# dnf install -y firewalld
# systemctl start firewalld
# systemctl enable firewalld
# firewall-cmd --zone=public --permanent --add-service=http
# firewall-cmd --zone=public --permanent --add-service=https
# firewall-cmd --reload

Install several required packages for server configuration and the
EPEL repository.

# dnf install -y vim wget dnf-utils epel-release

Micro tutorial for vim

A file opens with the command

# vim <fişier>

To write a test in a file, activate the insertion mode pressing the “i” or “INSERT” key and then you can write.
To add text from the clipboard, after entering the insertion mode, press SHIFT + INSERT or right click.
To save and close the file, first exit the insertion mode by pressing the “ESC” key, then type the text below and press ENTER

:x

Install Nginx

To add the official Nginx repository, create file Nginx.repo in /etc/yum.repos.d

# vim /etc/yum.repos.d/nginx.repo

Add the below code in the file and save it

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

Install Nginx, start the service and activate it to automatically start at reboot

# dnf install -y nginx
# systemctl start nginx
# systemctl enable nginx

Check the installation by opening the browser and access the server address.

Install MariaDB

If you install MariaDB from the CentOS repository, it will install version 10.3 (at this moment). MariaDB has an official repository, so add it and install version 10.4.

# vim /etc/yum.repos.d/MariaDB.repo

Add the below code in the opened file and save it

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/centos8-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

Install MariaDB, start the service and activate it to automatically start at reboot

# dnf install -y boost-program-options
# dnf --disablerepo=AppStream install -y MariaDB-server MariaDB-client
# systemctl start mariadb
# systemctl enable mariadb

Execute the script to secure MySQL/MariaDB and set a password for root

# mysql_secure_installation

Install PHP

PHP doesn’t have an official repository, so we use an external one that contains the required packages. We will use REMI.

# dnf install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm

By default, REMI has deactivated all repositories. To install PHP from REMI, you must activate the desired version. In this case, latest stable version is PHP 7.3

# dnf -y module enable php:remi-7.3

Now you can install PHP-FPM.

# dnf install -y php-fpm php-mysqlnd php-common php-json php-pdo php-cli

Depending on the application/site needs, you must install the necessary and specific packages.

Note: php (simple) package wasn’t installed because we don’t need it. That package is required only when you use PHP with Apache.

Configure PHP-FPM

A recommendation for a (small) security enhancement is to edit php.ini

# vim /etc/php.ini

and set

cgi.fix_pathinfo=0

We keep the reason and make another change. By default, PHP shows the version of the header received by the browser. To remove the version, in the same file, look for and set

expose_php = Off

Edit www.conf

# vim /etc/php-fpm.d/www.conf

Using nginx, the following parameters need to be changed: user and group

user = nginx
group = nginx

Change the listen parameter and set it as below

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

Uncomment listen.owner and listen.group parameters and set the right

listen.owner = nginx
listen.group = nginx

Start PHP-FPM and activate it to automatically start at reboot

# systemctl start php-fpm
# systemctl enable php-fpm

Note: At this moment, Nginx is not configured to serve PHP pages. We’ll set it up later.

Install Google PageSpeed as a dynamic module

Google offers an official repository only for Apache. For Nginx, we will add a repository from getpagespeed.com.

Warn: The installation of Google PageSpeed from the below repository only works if you have installed Nginx from the official repository and not from the CentOS repository.

# dnf install -y https://extras.getpagespeed.com/release-el8-latest.rpm

Install Google PageSpeed

# dnf install -y nginx-module-pagespeed

Note: At this moment, Nginx is not configured to use the PageSpeed module. We’ll set it up later.

Install Let’s Encrypt

It’s inappropriate to say Let’s Encrypt installation because it just emits the SSL/TLS certificates. Because the validity of certificates is only 90 days, it would be preferable for these certificates to be renewed automatically. For this, we will install CertBot

# wget https://dl.eff.org/certbot-auto
# mv certbot-auto /usr/local/bin/certbot-auto
# chown root /usr/local/bin/certbot-auto
# chmod 0755 /usr/local/bin/certbot-auto

Configure Nginx

Nginx creates a default configuration file for a domain. It needs it to be changed.

# vim /etc/nginx/conf.d/default.conf

Below are the changes, but at the end you have an example of a configuration file with all of them (for the casastii.nanlucian.com subdomain example), keeping the default Nginx comments and adding others for the new sections but removing the commented and unused directives. Changes are:

  • set server_name with your (sub)domain
  • in location / { } section, you find root and index directives. Move them up a “level”, in server { }
  • add index.php in index (preferably would be the first)
  • in location / { } section add try_files $uri $uri/ =404;
  • uncommet error_page   404 /404.html;
  • uncommet location ~ \.php$ { } section and add there the line: try_files $uri $uri/ =404;

Example with all the changes made (what is red is different as the default setting, but most of them must be changed as needed):

server {
    listen 80;
    server_name casastii.nanlucian.com;

    #following 2 lines are moved from: location / { }
    root /var/www/html; #must be configured the right path
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    error_page 404 /404.html; # uncommented line

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    # pass the PHP scripts to FastCGI server listening on /run/php-fpm/php-fpm.sock
    # the following section was uncommented
    location ~ \.php$ {
        try_files $uri $uri/ =404;
        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;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny all;
    }
}

I recommend to change the file name from default.conf in <domain>.conf.

You previously installed the PageSpeed Google module. Follows the activation in /etc/nginx/nginx.conf

# vim /etc/nginx/nginx.conf

Before to start any section (e.g.: events { } ), load the pagespeed module adding the following line

load_module "modules/ngx_pagespeed.so";

In http { } section, add

pagespeed FileCachePath /var/ngx_pagespeed_cache;
pagespeed on;

After saving and closing the file, create the cache directory and set the nginx owner

# mkdir /var/ngx_pagespeed_cache
# chown nginx:nginx /var/ngx_pagespeed_cache

By default, PageSpeed shows the version in the browser header. I recommend hiding it for security reasons. The fewer particularities you show from your server configuration, the better. In addition to the module’s usage settings, before the pagespeed on; line, add the setting:

pagespeed XHeaderValue "Custom message instead version";

By default, Nginx shows the version in the browser header. For security reasons, it is preferable to disable version viewing. You can do it in /etc/nginx/nginx.conf file. In http { } section, add

server_tokens off;

Do not forget that after completing the changes in Nginx, check the syntax of the configuration files and (if there is no error) restart the service.

# nginx -t
# systemctl restart nginx

Generating the SSL/TLS certificate

Having domain/domains configured in Nginx, you can generate the SSL/TLS certificates. When generating with the command below, Certbot will offer you the option to automatically change the Nginx configuration files and set the HTTP to HTTPS redirection and the use of certificates. If you want to make these changes manually, add to the end of the command: certonly

# /usr/local/bin/certbot-auto --nginx

And as I said above, it would be preferable for these certificates to be automatically renewed. For this edit the cron

# crontab -e

and add a line similar to the one below (Certbot recommends 2 times/day). At the line below, I recommend you to change the written hours.

0 3,15 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot-auto renew

To create a virtual machine (VM), many hosting services offer the option to use cloud-init for a faster initial configuration. I created a file that you can use it as a template for the cloud-config section. You have to do some changes, mentioned in the file itself.
Notă: last time when cloud-init file was updated is on configuration: CentOS 7.6, Nginx 1.14.2, PHP 7.3.1, MariaDB 10.3.12, Google PageSpeed Module 1.13.35, Certbot 0.29.1 (for Let’s Encrypt).

webserver.cloud-init

Leave a Reply

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

*

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