How To: Nginx, PHP-FPM, MySQL, phpMyAdmin, Postfix on Ubuntu

I recently moved to a new VPS because my last one was at something like 92% uptime. I wanted to try Nginx because Apache was constantly crashing, possibly something to do with Plesk being installed.

The resource usage on my old VPS was way too high considering I was running about a dozen mostly very low traffic websites, I don't really think I should have to tune a server much to handle that kind of pathetic load. So I made the move to Linode.

I've had a Linode in the past and the uptime/performance was excellent over the 5 years I had it. This time I also wanted to try out Nginx and scrap Plesk which also saves me about half my hosting costs right off the bat. This post will be mostly linking to tutorials I found useful.


It's actually very easy to set up Nginx, I followed these instructions to install Nginx with PHP5, PHP-FPM and MySQL. That will get you up and running and give you an excellent starting point to set up your virtual hosts.

Virtual Hosts

After getting that test running try out setting up basic virtual hosts directives, the Nginx config syntax is very easy to pick up and actually has some similarities to Apache with variable names etc.

At this point you might want to try out setting up SilverStripe on Nginx. Because .htaccess is ignored by Nginx much of what is in the .htaccess files in SilverStripe needs to be converted to the virtual host directive in Nginx (see the comments on that page).

User Pools

Now that you have some virtual hosts working, time to consider security and user management. I wanted to have users on my VPS that could access (via SSH or FTP) certain websites - and not other parts of the system.

Apache seemed to be spinning out a lot of processes on my old VPS, as a friend mentioned to me this was likely because Plesk sets up a seperate user for each website. Which is good to keep users on the system isolated, but tends to chew through the RAM (relevant).

I wanted to have some seperate users still, rather than resorting to a single monolithic user. Setting up user pools for Nginx seems like the perfect solution. Reducing the number of users, but keeping groups of websites isolated.

You should be able to set up some user accounts and even FTP into the server via SSH on port 22 to put a website up. Note: SFTP was bloody slow for me, might be easier to use scpto transfer those files.


You should have MySQL set up already, installing phpMyAdminis reasonably trivial.

Mail Server

I wanted to avoid running a mail server as much as possible, but in order to send emails from PHP scripts you will still need a mail transfer agent (MTA).

At first I thought about relaying all the mail to the gmail SMTP server but that has certain limitations and didn't seem like a very clean solution. In the end I settled for installing Postfix and configuring Postfix to run as my own mail server(as opposed to satellite) everything just worked after that.


I find FTP quite handy at times although I prefer to use Git. Setting up an FTP server is fairly straight forward and installing Git is just a matter of "sudo apt-get install git-core" basically. After that I configure Git to deploy my websiteseasily with a single command.

Speed test

Run some tests to see what sort of performance improvements have resulted, it's quite easy to install and try out Seige, as you can see there was a noticable improvement after I switched which could be put down to many factors but generally the hardware specs of my old VPS and my new Linode were the same. Old and busted:

$ siege -c 10 -r 10 -b
** SIEGE 2.72
** Preparing 10 concurrent users for battle.
The server is now under siege..      done.

Transactions:                    91 hits
Availability:                 91.00 %
Elapsed time:                 24.45 secs
Data transferred:             0.31 MB
Response time:                  2.04 secs
Transaction rate:             3.72 trans/sec
Throughput:                  0.01 MB/sec
Concurrency:                  7.61
Successful transactions:          91
Failed transactions:                9
Longest transaction:             8.15
Shortest transaction:             0.84

New hotness:

$ siege -c 10 -r 10 -b
** SIEGE 2.72
** Preparing 10 concurrent users for battle.
The server is now under siege..      done.

Transactions:                   100 hits
Availability:                100.00 %
Elapsed time:                 16.40 secs
Data transferred:             0.37 MB
Response time:                  1.52 secs
Transaction rate:             6.10 trans/sec
Throughput:                  0.02 MB/sec
Concurrency:                  9.26
Successful transactions:         100
Failed transactions:                0
Longest transaction:             3.07
Shortest transaction:             0.91


That's it. A few hours later you've got yourself a pretty sweet server.