NGINX + PageSpeed, MariaDB, PHP-FPM, NodeJS, Redis, Memcached backend

Pre-reading

Two weeks ago, I revealed my updated website and spoke about rewriting certain articles.
One of them is my “High performance backend” guide, I originally wrote around 2 years ago.

Webserver

Let’s start with the basics. Every website needs a webserver - otherwise we cannot deliver our content to the WWW.
While most distros come pre-packed with Apache, I highly discourage from using it.
Don’t get me wrong, Apache is great, if you are a beginner and just want to get something running.
However, performance wise it’s not anywhere near to NGINX.

Especially with KOXHA.DE, where most files are static NGINX is way, way, way faster and efficient to Apache.

Of course - one could argue that there are better alternatives like Caddy or OpenLiteSpeed, but did you every thought about running NGINX with PageSpeed?

For those, who do not know PageSpeed helps to rewrite and optimize resources on your website.
Basically one could compare it with CloudFlare’s optimization features, just as some sort of self hosted version.
Unlike CloudFlare though there is no delay during delivery (you do not want to lose 1s just to CloudFlare - trust me)
and with appropiate setup you can achieve even greater speeds.

Since we are targeting bleeding edge features we will compile NGINX mainline and go straight for TLS 1.3.

MySQL vs MariaDB

Aren’t both the same? Kinda. MySQL used to be MariaDB’s predecessor until it was bought by Sun Microsystems in late 2008, which in return was bought by Oracle in 2010. However, in 2009 Monty Widenius, the core developer of MySQL, decided to create a fork called MariaDB, which targets to be mostly compatible to MySQL, making it a perfect drop-in replacement.
There are multiple reasons why this happened, one of them being Oracle moving the project more to a closed source direction, which in return caused open source distros to replace MySQL with MariaDB.

Having that said, our decision should be pretty clear. We want to go with MariaDB.

NodeJS

If you wish to install NodeBB or Ghost make sure to install this.
In case you are not really sure, if you need this make sure to check the documentation of the software you want to install.

Redis

What about Redis though?
I don’t need NoSQL, do I?
Back in the days I wrote this guide with NodeBB in mind, which used to run with Redis.
Nowdays they switched the default database to MongoDB rendering the installation of Redis obsolete.

However, in combination with PageSpeed Redis introduces interesting opportunities, offering high performance caching.
Furthermore, this also might be interesting for those of you, who wish to run an OnlyOffice server as well (e.g. for Nextcloud).

Personally I would discourage from using it, unless you know what you are doing or really need it.
Especially, if you run a machine with low memory I do not recommend using it at all.

PHP

PHP stands for Hypertext Preprocessor and is a programing language commonly used by most websites and their respective software backends.
Examples for the use of PHP are WordPress or Joomla, but also Nextcloud requires you to run PHP.
Since we are using NGINX it is required to install PHP implemented under FastCGI aka PHP-FPM.
You can find the configuration files for PHP-FPM in the GitHub repo linked at the end of this article.

Installation

Time to get to the actual installation.
The following commands were tested under Fedora 30, but might as well work for CentOS 7, 8 and probably most other RHEL distros.

NGINX

Let’s beginn with installing NGINX.

# Requirements
yum install gcc-c++ pcre-devel zlib-devel make unzip libuuid-devel perl nano memcached

# PageSpeed
# Check https://www.modpagespeed.com/doc/release_notes for latest version
NPS_VERSION=1.13.35.2-stable
cd
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v${NPS_VERSION}.zip
unzip v${NPS_VERSION}.zip
nps_dir=$(find . -name "*pagespeed-ngx-${NPS_VERSION}" -type d)
cd "$nps_dir"
NPS_RELEASE_NUMBER=${NPS_VERSION/beta/}
NPS_RELEASE_NUMBER=${NPS_VERSION/stable/}
psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_RELEASE_NUMBER}.tar.gz
[ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
wget ${psol_url}
tar -xzvf $(basename ${psol_url})  # extracts to psol/

# OpenSSL
# Check https://www.openssl.org/source/ for latest version
OPENSSL_VERSION=1.1.1d
cd
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
tar -xvzf openssl-${OPENSSL_VERSION}.tar.gz

# NGINX w PageSpeed and OpenSSL
# Check https://nginx.org/en/download.html for latest version
NGINX_VERSION=1.17.6
cd
wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
tar -xvzf nginx-${NGINX_VERSION}.tar.gz
cd nginx-${NGINX_VERSION}/
./configure --add-module=$HOME/$nps_dir ${PS_NGX_EXTRA_FLAGS} \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/lock/subsys/nginx \
--with-openssl=/root/openssl-${OPENSSL_VERSION} \
--with-stream \
--with-stream_ssl_preread_module \
--with-http_secure_link_module \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module
make
make install

NodeJS

Followed by the installation of NodeJS.

# NodeJS
curl -sL https://rpm.nodesource.com/setup_13.x | bash -

MariaDB

Let’s continue with MariaDB.
Run nano /etc/yum.repos.d/MariaDB.repo and enter the following.

# MariaDB 10.4 Fedora repository list - created 2019-11-16 05:27 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/fedora30-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

Save with Ctrl + X and confirm with Y.

The install MariaDB with the following command.

yum install MariaDB-server

PHP-FPM

Time to install the last piece of our puzzle - PHP.
The following command should cover the mostly used extensions.

yum install php-fpm php-cli php-common php-apcu php-gd php-igbinary php-imagick php-imap php-intl php-json \
php-mbstring php-mcrypt php-memcached php-mongodb php-msgpack php-mysqlndphp-PDO php-pear php-process php-redis \
php-xml php-opcache php-zip

Make sure that you set cgi.fix_pathinfo = 0 in your php.ini.

NGINX Autostart & Configuration

To finally run NGINX you need to create a service.

Enter nano /lib/systemd/system/nginx.service and paste the following information.

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/local/sbin/nginx -t
ExecStart=/usr/local/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Once done enter the following commands, which will load the service, make it run at boot and start it.

systemctl daemon-reload
systemctl enable nginx
systemctl start nginx

Congrats, you are all setup and good to go.

Extras

Memcached

As you might have noticed we installed Memcached at the very begining.
The reason for this is that its one of the default caches of PageSpeed.
You can find its config file in /etc/sysconfig.
Be sure that you change the memcached user to the same user as NGINX (usually nobody).
Otherwise, PageSpeed won’t be able to run properly.

Certbot

If you want to run a free SSL certificate, you might as well want to install Certbot.

yum install certbot

RAMDisk

If you are running a machine with a lot of memory, you might want to share some for caching purposes.
The following code block will create a 512MB RAMDisk and mount it under /mnt/ramdisk.
Keep in mind to use your RAMDisk ONLY for caching or other non crucial things as EVERYTHING stored there will be lost, once you reboot or switch the power off.

mkdir -p /mnt/ramdisk
mount -t tmpfs -o size=512M tmpfs /mnt/ramdisk
grep /mnt/ramdisk /etc/mtab | sudo tee -a /etc/fstab
chown -R nobody:nobody /mnt/ramdisk

Redis

For those who need to run Redis, just run:

yum install redis

Then enable and start it.

systemctl enable redis
systemctl start redis

Security

Here a few very basic tipps to secure your server properly.

  • Change your SSH port
    The most basic thing you can do is to change your SSH port from 22 to any other you like.
    The config file for SSH can be found under /etc/ssh/sshd_config.
    Just make sure that you don’t set the port to any other default port like 21, 25, 80, 443, 3306 and so on.
    Most of those ports are occupied by other services.

If you do not know, which ports are in use you can run lsof -i -P -n | grep LISTEN and get a list of all currently used ports.

Other ideas to secure your SSH login are Fail2Ban, do not permit root login (instead go over a sudo user) and the use of keys, instead of passwords.

  • Set a Redis password
    I cannot stress this one enough!
    Even though Redis default config has been changed to no longer run in public, many people just go and reveal the instance to the public without having a password set.
    5 minutes later their RedisDB has been emptied or occupied by somebody else and they just wonder why.
    Don’t be fooled and set a secure (+16 chars) password in your Redis config!!!

Config files

If you want to see some config files, head over to my GitHub.
Even though I did not update some of those files a long time ago, they are still pretty recent and work just fine.

0%