Running a website on a budget and still want the best performance? Not a problem with NGINX and GooglePagespeed. This guide covers it all, including a sample installation of NodeBB.

Pre-reading

Some might say, that this is overkill and I agree - this is by far way more than you need. Actually, its so much that beginners will get caught up in this for sure. On the other hand this is definitely the way to go, if you want to make your website fly.

Forget all the adverts providers, CloudFlare and others make - this is the real deal. Free of cost, open source.

The reason why I am sharing this knowledge is because I have been for a very long time a passionate webmaster on my own. During this time I often met webmasters, which sites featured great content, yet their sites failed, due to missing knowledge to make their great content "shine".

Going for "as good as you can" is not enough, it never is. We live a world, where time is valued more than everything else. Therefore, the first step to be ahead of others, is to be the fastest.

Its time to give your content the backend it always deserved.

Server

Picking the right server is a difficuilt and quite sensitive task. If you pick a too underpowered system you will run out of resources fast. If its too expensive though, you will run out of cash.
So what is enough and what is luxury?

Most people will tell you to either try Linode, DigitalOcean or Vultr. However, for the 5$ you pay, you are getting some overpriced hipster box. If you are really low on cash I can recommend OVH. In my opinion the performance offered there is fairly decent and way better compared to DO for example. Alternative you should check out Online.net's "ScaleWay" x86 boxes. While the CPU is not that great, the VPS's are just fine to kick of for a few bucks. For German/EU users I can also recommend using netcup. Its pricey at times, however they often have great promotions and offer by far the best hardware on the market.

Please note that this is just my personal opinion. In the end it depends on you, how much you are willed to spend and where. I personally would use a VPS/Server with at least 2GB of RAM. This should be enough for most use cases.

OS

While you can use any OS, you are comfortable with, I will only provide the commands for Ubuntu here and so do recommend you to use it as well.
Why? Because, if you are reading this guide I will assume you are a beginner.
Furthermore Ubuntu Server has in general the greatest documentation as its quite popular.

Good choices are also FreeBSD or CentOS. Basically it doesn't really matters.

Preperation

Assuming you have installed Ubuntu Server 18.04LTS on your server, its time to get it running. If you are using Windows on your PC, I do recommend to install WinSCP and PuTTY. Instead of WinSCP you can of course use FileZilla. However, my personal experience confirmed that WinSCP is far more convenient to use. Maybe try both and decide which one you like more.

Additionally I recommend using a text editor with syntax/highlighting, e.g. Sublime or Atom.
Even though we will not really use them in this guide, its always recommended to have a proper text editor on your PC, in case you want to make edits to your configs locally. Without highlighting you tend to mess up configs.

DNS

What has DNS to do with a stack? Not a lot, thats right, but as said we will target the maximum possible performance. Therefore, we will also try to reduce the DNS resolving time.
To achieve this we will route our domain through CloudFlare. Just sign up and follow the instructions. Once done be sure to have DISABLED CloudFlare in the DNS settings (grey clouds).

Why thoough? Due to the use of CloudFlare the server response time can be delayed around 0,7s, which is quite a lot, considering we want to achieve loading times way faster than that. Instead we will just make use of CloudFlare's fast DNS network.

Security

Open up PuTTY and enter your servers IP. By default the SSH port will be set to 22. Once you entered your password and successfully logged in, its recommended to change the SSH port.
To achieve this I recommend running the following commands:

apt-get update && apt-get upgrade
apt-get install nano
nano /etc/ssh/sshd_config

Check out for the line writing:

Port 22

Change it to a number like 198 for example. Once edited hit Ctrl+X. Confirm with Y.
Now you need to restart SSH:

service ssh restart

Thats the most basic security I do recommend. Of course there are more practices like Fail2Ban, Firewalls and so on. However, this guide is directed at beginners and covers the most basic commands to admin a server.

Between, did you notice how we updated our sources and upgraded our system with the first command? Neat.

Webserver

By default Ubuntu Server might have a couple of useless crap installed which will be blocking in our use case. To remove it run the following commands:

apt-get remove httpd* apache* nginx* mysql* php*
apt-get purge httpd* apache* nginx* mysql* php*

All clean and ready to use. Now we can start setting up our own webserver.
As you might have heard there are plenty webservers. The two most commonly used ones are NGINX and Apache.
Unfortunately I have encountered webmasters still using Apache in 2017. NGINX is far more efficient and performant.
Therefore, the choice is quite easy. However, we won't install NGINX over the apt repo. Instead we will build it from source.

But why? Isn't it harder to setup? Sure it is, but at the same time we will add some goodies to our NGINX version.
One of them will be Google PageSpeed. Yep, TLSv1.3 will be supported as well.
Our goal is maximum performance at maximum stability and security. Lets go for it.
Lets first clone some of the required modules and also install some libraries.
Before doing so, we will install git, since we are going to need this later when installing NodeBB.

apt-get install git

General dependencies necessary for compiling:

apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip uuid-dev

Now we can start compiling NGINX!

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_VERSION=1.1.1b
cd
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
tar -xvzf openssl-${OPENSSL_VERSION}.tar.gz

NGINX_VERSION=1.14.2
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-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

Please note that Google PageSpeed, OpenSSL and NGINX might update from time to time. Therefore I recommend checking them for updates regularly.
To update NGINX or any of the modules, just rerun the above commands with their respective version numbers. Afterwards you just restart NGINX.

Well, thats it. Almost. Now we need to be able to start and stop NGINX and also let it auto boot.
To achieve this we will create a script:

nano /lib/systemd/system/nginx.service

Paste this into it:

[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

Close with Ctrl+X, confirm with Y.
Reload systemd services:

systemctl daemon-reload

Enable NGINX on boot:

systemctl enable nginx

You can now verify whether or not NGINX is running by entering:

service nginx status

Starting NGINX manually can be done with:

service nginx start

Congrats on your succesful setup. Next we will install a Database system.

Database

Before even thinking about NodeBB, we will install a classical SQL database server for later use, e.g. WordPress or Ghost.
Lets pick MariaDB. Instead of posting the instructions here, I recommend checking out this link:
https://downloads.mariadb.org/mariadb/repositories

Everything is explained there.

Now lets get onto NodeBB. Instead of MongoDB, we will skip into the future and go with Redis. Super fast, super simple.

REDIS_VERSION=5.0.4
wget http://download.redis.io/releases/redis-${REDIS_VERSION}.tar.gz
tar xzf redis-${REDIS_VERSION}.tar.gz
cd redis-${REDIS_VERSION}
make
make install
cd utils
sh install_server.sh

Follow the on screen instructions and configure the vars to your desired option.
By default the service name will be redis_6379.

Assuming your redis.conf is in /etc/redis/redis.conf, you want to make sure its bound to 127.0.0.1.
If not uncomment the line.
Also be sure to use a password for authentication. Search for requirepass and replace the default password.
Please be sure to give this article a quick read as well:
https://redis.io/topics/security

Especially the tipps with "renaming" should be considered to prevent data being manipulated by a 3rd party.

You are done now.

PHP

Instead of old fashioned, RAM hungry PHP-FPM, we will go for HHVM. A drop-in PHP replacement.

apt-get update
apt-get install software-properties-common apt-transport-https
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xB4112585D386EB94

add-apt-repository https://dl.hhvm.com/ubuntu
apt-get update
apt-get install hhvm
sudo update-rc.d hhvm defaults

Running HHVM in socket mode gives a little extra performance.
Replace the entire content of /etc/hhvm/server.ini with this:

; php options
expose_php = 0
pid = /run/hhvm/pid

; hhvm specific

# hhvm.server.port = 9000
hhvm.server.file_socket=/run/hhvm/hhvm.sock
hhvm.server.type = fastcgi
hhvm.server.default_document = index.php
hhvm.log.use_log_file = true
hhvm.log.file = /var/log/hhvm/error.log
hhvm.repo.central.path = /run/hhvm/hhvm.hhbc

Restart hhvm:

service hhvm restart

To get HHVM running with NGINX, check out the configs attached.

NodeJS

Installing NodeJS will be even easier.
All you need to run is:

NODE_VERSION=10
curl -sL https://deb.nodesource.com/setup_${NODE_VERSION}.x | sudo -E bash -
sudo apt-get install -y nodejs

Hardcore.

NodeBB Installation

You can now start installing NodeBB according to the docs. As seen in my configs, I have got my NodeBB install running in /home/web/mydomainname.tld/.
Adjust it to wherever you feel comfortable with.

Bonus

Memached

PageSpeed can either be run by using Memcached or Redis. Since we do not want Redis to fed up, we will go for Memcache:

apt-get install memcached

Also be sure to raise its memory limit. To achieve this edit /etc/memcached.conf and change the given paramteres to your desired value.
I recommend a cache of around 512MB. Once completed be sure to restart memcached by using service memcached restart.

RAMDisk

If you have a machine with more than 2GB of RAM, you can use the additional memory to provide a RAMDisk. While RAM is volatile and therefore unable to keep data stored permanently, it doesn't matters for our cache.

Therefore, we will make use of the enormous speed RAM provides.

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

Once done, you can route PageSpeed to cache its files on the newly created RAMDisk. To do so edit the "pagespeed.conf" in the "conf.d" folder of NGINX.

Look out for "pagespeed FileCachePath" and adjust the directory.

Congrats to your stack.

Sample NGINX configs

https://github.com/ReyKoxha/sampleconfig