Setting up a new Linode with Nginx + PHP7-FPM and Ubuntu 16.04 LTS from start to finish

Setting up your Linode

If you are not familiar with Linode, they are a provider of VPS (Virtual Private Servers) which is basically a semi-private version of shared hosting. You generally don’t have to share the box with hundreds of other people and even if you do you are guaranteed a certain share of the resources (CPU / RAM / etc). Not to mention the server hardware itself is extremely beast as far as power. You are in your own little private eco-system meaning you and only you have access to your machine (or slice of a machine rather). You will not experience the same horrible load times and transfer rates that you would get at companies like Go Daddy and Dreamhost (shudder). The only down side is you do not have a CPanel or Plesk panel (though you can install one if you wish, but I do not use them and will not go into that here) so you have to install and manage everything yourself. It’s not as hard as you might think if you can get used to searching Google and reading a lot of tutorials.

Command line can be a tricky beast for beginners, this blog aims to help ease some of that pain by sharing the procedures that I usually take when setting up my web server. Please be advised that with every new version of Linux the steps can vary a bit due to packages being upgraded or removed from the repositories.

This guide focuses on configuring the latest and greatest (at the time of this article) version of Ubuntu on a freshly provisioned Linode server. The exact system specs do not matter that much, you can use the lowest 1G plan if you like, the steps will be the same. I’m using the cheapest plan that costs $10 a month. You can check out Linode’s prices and decide for yourself.

Provision your Linode

This is the easiest step thanks to Linode’s user friendly UI. Simply add a new Linode, select your desired size from the options presented. You can always increase the size at a later date so feel free to select the smallest size you are comfortable with.  On the dashboard for the newly created Linode you will need to find the link “Deploy a Linux Distribution”. Select the latest version of Ubuntu which is at the time of this article “Ubuntu 16.04 LTS”. Type a root password in the input box and hit the Deploy button. Wait for the tasks in the job queue to all show success and then click the “boot” button to fire your machine up.

The first stage is finished, congratulations! Now for the real fun stuff!

Connect to your server

Open up a terminal so you can connect to your newly created Linode server. If you are on Linux or Mac this should be pretty self explanatory, but on Windows you have to install a third party software called Putty. In putty you will have a GUI to type in the IP address and user. You can get your IP address from the Linode Manager simply click “Linodes” on the top menu and it should list your Linodes with the IP address visible. It is also visible on the “Remote Access” tab of your Linode’s Dashboard.

You will then be prompted to provide the root password that you specified when you provisioned the Linode. This will log you into the server and drop you at the command line.

Basic Ubuntu Setup

The following stuff is some pretty basic Ubuntu configuration you should make before doing anything else.

Set the hostname

This can be anything, generally I just specify a short version of the full domain. (i.e. would become cooldomain)

You can verify it was set correctly by typing:

Set the fully qualified domain name

Now you can set the FQDM by making sure the following is in the /etc/hosts file.

Set the time

You can verify that it’s correct by typing:

System updates

Now is a good time to make sure you have all the latest system updates

Adjust swappiness

I generally like to modify swappiness so it only uses swap if it absolutely has to. You can do this pretty simply like this

Now we need to add a line on sysctl.conf to make sure it keeps the setting after a reboot. So edit /etc/sysctl.conf and add this line to the bottom

Security Precautions

Here’s some basic steps you can take to improve the security of your server a bit.

Create new user

You should not be connecting as root on a regular basis, so we will create a new user that you can use from now on.

Then you are going to want to put that user into the sudo group so you can execute commands as root

Now we need to test your new account to make sure it’s working because the next step is to disable logging in as root.

Disable root login

If you can log in successfully then we are good to go for the next stage, lets disable root login.

Look for the line that says “PermitRootLogin” and change it to “no

NOTE You can also change the SSH port in the sshd_config file if you desire. Just change “Port” to whatever you like. The default is 22.

Save the file and restart sshd

If you changed your port you will have to login as follows from now on:

Install UFW

Enabling a firewall is a pretty crucial part of any secure server. You can use either iptables or ufw. I have recently started using ufw because it’s really easy and no fuss.

This will install the firewall now we need to configure it.

Open some ports

Now lets open some common ports that we want to use. http, https, ssh, ftp, mail, etc

Lets enable it now

Pretty simple eh?

Install Fail2Ban

Fail2Ban is a security tool to prevent dictionary attacks. It works by monitoring important services (like SSH) and blocking IP addresses which appear to be malicious (i.e. they are failing too many login attempts because they are guessing passwords).

Now we need some basic configuration.

Restart the service for the changes to take effect.

Reboot server on out-of-memory condition

This is a really neat feature to turn on. Basically if your server runs out of memory it will throw an exception and reboot, which will cause a few minutes of downtime but that is waaaaay better than sitting there swapping for hours and basically being non-functional anyways. Add the following to the end of the file “/etc/sysctl.conf“:

Setting vm.panic_on_oom to 1 tells the server to throw a kernel panic when it runs out of memory. Setting kernel.panic to 10 tells it to reboot 10 seconds after panicking.


Install FTP server

FTP server is a useful thing to have for numerous reasons, one being some software like wordpress uses it to update itself or install plugins.

Now edit the config:

Make sure these settings are uncommented and or created

Save the file and restart vsftp:

Install some useful software

These aren’t required but this is a running list of some stuff I generally install on new servers

Forward domain e-mail to Gmail

Setting up an e-mail server is a very complicated and often frustrating experience. For that reason I do not use it myself. Instead I simply want email sent to my various domains to be forwarded to my personal Gmail address. This is what I will cover below. We start by installing postfix

Just leave all the settings default

Now we need to do a little tweaking to the config file.

Add the following lines at the end (replace with your server’s domain):

You will also need to add any domains you wish to forward emails from onto the mydestination line like so

Save the file and open up the virtual config:

Now you can configure your forwarding rules. The most basic is a catch-all but you can also input specific email addresses and where you want them forwarded. Here is a catch all example:

For a specific address you just add the preceeding mailbox

Save the file when you are finished and run postmap, this will load the new forwarding rules.

Go ahead and restart postfix for good measure.

It’s important to note that if you are forwarding to a gmail account any test e-mails you try sending to the domains from the same address the server is forwarding to will not reach your e-mail box. This is something on gmails end. To properly test forwarding you will need to send an email to your server from a different gmail account or from a non-gmail account.

Forward mail to system accounts to /dev/null

You may want any mail sent to specific system users to be sent to the void (aka deleted). You can’t directly send mail to /dev/null with the virtual file but you can create a system alias and have it sent there.

Add this line to the file

Now edit your virtual database to add the forward rule

Add a line for each box you want sent to /dev/null

Run postmap again and you are good to go

Installing Nginx and PHP7-FPM

So we have a basic server configured now we need to install the most important aspect, the web server itself. I greatly prefer Nginx to Apache because of it’s much lower memory footprint / requirements. In the past I have used spawn-fcgi to run php as fastcgi to serve pages. I’ve since abandoned it for php7-fpm which is much simpler to get running and a lot less manual labor.

Install the Nginx Web Server

First things first lets install the web server.

In Ubuntu 16.04 Nginx will automatically start upon installation. You can test it now to see if it’s running by inputting the domain or ipaddress of the server into your web browser. If for some reason you don’t have a domain or don’t know your ip address you can quickly get it by typing this on the command line:

Another option is to curl one of the various ip address websites like so:

You should see a Welcome to Nginx web page in your browser if everything went according to plan.

Install any databases you want to use

The most common databases would be either MySQL or PostgreSQL, install both of them if you like or only the ones you want to use

Now complete the process by securing your installation

You’ll be asked to enter the mysql root password that you specified during installation.

After this process is finished MySQL should be ready to go.

Install PHP7

Now we need to install PHP to complete our web stack. Since Nginx does not have native PHP support we will need to run PHP as fastcgi via php7-fpm, which stands for “fastcgi process manager”. We will tell Nginx to pass PHP requests to this software for processing.

Now you need to configure the php processor.

We are looking for a line “cgi.fix_pathinfo” this line should be commented out with a semi-colon and set to 1. We need to uncomment this and edit it to 0 like so:

Save and close the file then restart php7.0-fpm


Lets tweak the pool setting on memcached to make it more efficient.

Now you want to find the line that begins with -m and modify it from 64 to 128

Save the file and close it.

Enable Gzip Compression

Basic Gzip compression should be on by default but we want to uncomment a bunch of lines in the config to fully enable it.

You are looking for a big block of settings that starts with “gzip on;” we want to uncomment all the lines to match below:

Save the file and that is finished.

Now restart nginx

Folder Structure and Nginx Virtual Hosts

Website folder structure

Now that we have all the packages installed we need to set up our folder structure that will house all of our domains. This is a pretty subjective topic and feel free to modify it to your liking. I’ll just supply an example folder setup that you can use if you so desire.

Under each domain folder I place four difference folders, this is the intended purpose of the different folders

  • public
    The web root for the production domain, all web accessible production files will go here.
  • dev
    The web root for the development version of the website. You can setup a sub domain such as dev. to point here.
  • private
    You should put any items that you do not want to be web accessible here. You can still access them through PHP to utilize in your web applications. Files here could be shared between production and dev, or in the case of ExtJS the main app code can be housed here.
  • logs
    The nginx error and access logs should be placed here.
  • backup
    If you want to run any sort of backups for a specific domain you can place the backup archives here.

First make the domains folder in your home directory

Then you can create the folder structure for each domain with a one liner pretty easily like this

Then you should make the logs folder writable

Nginx Virtual Hosts

Each domain that you want Ngnix to host will need it’s own virtual host file. These are all located at “/etc/nginx/sites-available/“. When you installed Nginx it automatically created a “default” virtual host. You can either delete this virtual host or use it for your primary domain. There are a few changes you’ll need to make to it first.

Here is the current default vhost file in it’s entirety.

You will need to change the “root” line to point to the domain’s path for the site you wish to serve

There is a line that lists the various index file types you’ll need to add index.php like so

You need to modify the server_name line to match your desired domain name

Below the server_name line add these two lines to setup the logging to our proper folders

If you are going to be using wordpress pretty urls on the domain you will need to add this block below the log lines

The final block you will need to add below the previous one is what sends the php traffic to php-fpm. Some form of this should already exist by default but commented out. Simply uncomment the required lines. Make sure to only uncomment one of the fastcgi_pass lines. (The one for FPM) as shown below.

Now for each new domain you wish to add you’ll need to add a new file to the sites-available folder. Here’s a full sample virtual host configuration.

NOTE I made the primary website www. in this example and the top server block redirects all traffic to the regular domain to www. This is not required, you can remove this if you wish and change the server_name in the primary block to remove the www.

After you save this file you will need to link it to the sites-enabled directory and restart nginx

The website should now be live. If you want to test it to make sure php is working you can create a new file in the domains public folder and output the results of phpinfo().

Now paste in the following code and save the file:

Now if you visit your domain at http://<domain>/info.php you should see the phpinfo page. Thats it for now. have fun!

Posted in Uncategorized

Leave a Reply

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