In earlier posts I briefly talked about the dramatic performance improvements you can get by using Nginx to run your PHP / WordPress websites and touched on some of the vital steps that need to be done to start tuning WordPress for performance.
If you’re interested in the idea of using Nginx but wondering where to start or are perhaps finding it a challenge to find a consistent & accurate guide on the web to get you up and running, then hopefully this post will help demystify things a little for you.
The steps below work, and should get you up & running with an operational Nginx server along with support for WordPress & PHP.
As an important set of caveats however, I’m not suggesting that this is everything you need to do in order to build a working server for you; guaranteeing this will work on any random OS you want to use; that this is the only way to end up with something that works… or to that matter, that the end result does everything you need it to! Your mileage may well vary!
They also do not cover installation of popular control panels such as Webmin/VirtualMin/cPanel etc. (as I don’t tend to use them) and won’t deal with moving email around for the simple reason that I always keep email & web services separate, normally handling email through a hosted Exchange solution or Google Apps.
The following instructions are based on starting with a fresh installation of CentOS 5.7 (or 6) and should result in a running web server using Nginx & PHP-FPM, ready to run WordPress.
The same basic configuration will work for both single WordPress instances & WordPress MultiSite, assuming you use the right Nginx config 🙂
Without further ado, SSH into your fresh CentOS installation and complete the following steps. Commands that need to be executed via SSH or a console prompt are prefixed with “>”.
Throughout, you can download copies of any mentioned configuration files by clicking the links.
Add the REMI Repository
While CentOS provide many packages through their own software repositories for easy installation via YUM for essentials such as PHP & MySQL, unfortunately in many cases those packages are woefully outdated and you end up with old versions of software installed on your server. In the case of Apache, MySQL or PHP it’s vital to stay up to date with current versions to ensure you’re protected from known bugs & security holes etc.
Fortunately, it’s very easy to setup an alternative repository to obtain access to newer versions of software without needing to start compiling your own from source and one of the most useful repositories for LAMP is Remi’s.
The commands to do this are a little different depending on whether you’re running CentOS 6 or 5.x, so please pick the right ones:
> rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
> rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
With the repository installed, the next step is to install MySQL, PHP & Nginx:
Starting with MySQL, this command should install both MySQL Server and all of its various dependancies.
> yum –enablerepo=remi install mysql-server
Once installed, we now need to start, enable the service & secure the installation.
> service mysqld start
Enable it as a service to automatically start whenever your machine is rebooted:
> chkconfig mysqld on
Next, the installation should be secured by setting a secure root password, removing test user accounts & databases and preventing remote login using the root account if possible in your environment. Just follow the prompts for this, supplying a suitable password & answering Yes to removing test databases/users & preventing remote root access.
Next, PHP & PHP-FPM should be installed:
> yum –enablerepo=remi install gcc php php-common php-pear php-pdo php-mysql php-pecl-memcache php-pecl-apc php-gd php-mbstring php-mcrypt php-xml curl php-devel php-fpm
Enable PHP-FPM & start the service:
> chkconfig php-fpm on
> service php-fpm start
Finally, install NGINX:
The simplest way to do this is to setup a new repository for NGINX – which along with simplifying installation also simplifies updates in the future.
First, we need to create a new YUM .repo file:
> vi /etc/yum.repos.d/nginx.repo
> yum install nginx
> chkconfig nginx on
> service nginx start
(more detailed install instructions can be found on the Nginx Wiki)
At this point, you should be able to visit http://your-server’s-ip and see a page welcoming you to Nginx.
Before going much further, I’d recommend that you take a moment to install & enable a firewall on your machine if it’s not already running one, and ensure that you open only the ports you actually need.
Summary: Assuming you’ve made it to here, you now have a server which contains a base installation of Nginx, PHP & MySQL; which will need further configuration to get a usable system up & running.
The most vital two steps here are to setup PHP-FPM to support PHP requests from NGINX, and then to configure NGINX to host websites along with passing PHP requests onto PHP-FPM.
In terms of configuration, PHP-FPM uses a service-based model with a relatively simple base configuration file which then loads service-specific configuration files for as many PHP process pools that you wish to start. For most installations a single “www” PHP poll is probably more than sufficient, and you should find a default configuration file waiting for you in /etc/php-fpm.d/www.conf.
Restart the php-fpm service to pick up the new configuration:
> service php-fpm restart
Next, we need to configure NGINX.
A similar model is used for NGINX with the base nginx.conf file defining your PHP handler (i.e. php-fpm), and site-specific conf files handling anything more er, specific.
Finally, we need to configure NGINX for your site & WordPress.
There are many, many ways to tackle this but assuming you’re planning to run more than one site on this machine, I would recommend creating a generic WordPress configuration file containing all necessary settings to run WordPress and including it in any site specific configuration.
Within a “global” folder, create a wordpress.conf file:
A number of restrictions should really also be defined in a global .conf file for potential re-use across multiple sites:
> vi /etc/nginx/conf.d/global/restrictions.conf
Then, finally, create a site specific configuration file which defines the site specific config you need such as domain names, root folders etc.
> vi /etc/nginx/conf.d/your_website.conf
Restart your NGINX service to pick up your new configuration, and assuming you’ve taken care of the more mundane aspects such as creating a database for your WordPress installation, uploading the necessary WordPress files, copying a default wp-config.sample file over to wp-config.php (and adding in your database’s name along with a username/password), you should now be up & running !