CAPITOLEFFECT
9Jan/10Off

Document, nginx+php-fpm+wordpress

Well I thought it would probably be a good idea to log all this down in case I need it in the future. After trying out nginx+spawn-fcgi and having dismal problems with 502 errors my friend Ryan suggested I use php-fpm instead. It's what he uses on his servers to get a good speed and stability for his sites.

The whole process probably took me about 5 hours in total. The steps are quite easy but I had issues with switching my DNS and forgetting to compile essential items into PHP. I also had to migrate an existing Wordpress setup (using the same domain name thank goodness) which not everyone has to do of course as well as troubleshooting a bleeding edge copy of Kronblr.

Note: This isn't a tutorial as such, it's all the steps I need to remember in case I need to do this again in the future. But take what you will :)! Watch out for my randomly changing perspective in this post. It's not very consistent from a writer's view.

What I Have

  • The Rackspace Cloud Server (Ubuntu 9.10)
  • nginx, MySQL, build-essentials, various dev libraries (all installed from default Ubuntu repositories, version doesn't matter)
  • PHP 5.2.11 + PHP-FPM, phpMyAdmin (installed from source, version doesn't matter as long as there is an FPM patch available)
  • WordPress 2.9.0 (installed from package retrieved from WordPress release archive, needed this specific version as that was what I was migrating from, alter to suit)
  • CDN Tools, WP Super Cache (free WordPress plugins, compatible versions with WP at the time)

What I Read

What I Listened To

What I Ate

I'll go through the steps in the general order I did them. Some steps are essential if you want to end up with a working dynamic site at the end of the process. But I'm too lazy to flag them :/!

1) Provision Server

In order to begin a clean install I provisioned a new The Rackspace Cloud Server instance through their control panel. I normally go for smaller instances as I don't get much traffic and my server footprint is very low. I highly recommend the The Rackspace Cloud not only because of their low price but the benefits of using their Cloud Files CDN service (more on the extra benefits of this later).

  • Setup server specific A record on DNS (servername.domain.tld)
  • Configure
    • reverse DNS to match whatever you want (in my case domain.tld)
    • any other A records that you want pointing to the server
    • user on server with SSH key for easier access
    • any other server options you like to use
  • I know it's linux but restart the server just once, sometimes it helps a lot

2) Grab the files you need from every which where

We need to grab the content from the Ubuntu repositories that don't need to be specific to a particular version. This includes development libraries and apps that are useful.

Alrighty let's get started with all the apps that are going to be needed.

apt-get install build-essential subversion nginx mysql-server bison flex patch autoconf locate gitosis screen

The packages below are for when you need to compile PHP.

apt-get install libxml2-dev libbz2-dev libpcre3-dev libssl-dev zlib1g-dev libmcrypt-dev libmhash-dev libmhash2 libcurl4-openssl-dev libpq-dev libpq5 libsyck0-dev libpng-dev libjpeg-dev libxslt-dev libmysqlclient-dev

We now have all the basic files needed to setup the server. Note: It's possible I have missed some packages I used and some of these may not actually be needed but if you run into problems do a Google search and figure out if you need anything else. Now is a good time to configure nginx to work and serve basic files.

3) Setup nginx to serve files

This is actually really easy. Firstly we should add 'xsl' and 'xslt' to the /etc/nginx/mime.types file next to xml. This will be needed to use Kronblr. Next we need to make a site declaration in /etc/nginx/sites-available and link it to the /etc/nginx/sites-enabled folder.

server {
    listen   80;
    server_name capitoleffect.me www.capitoleffect.me;
    access_log /home/capitoleffect.me/logs/access.log;
    error_log /home/capitoleffect.me/logs/error.log;

    location / {
        root   /home/capitoleffect.me/www;
        index  index.html index.htm index.php;

		# this serves static files that exist without running other rewrite tests
		if (-f $request_filename) {
			expires 30d;
			break;
		}

		# this sends all non-existing file or directory requests to index.php
		if (!-e $request_filename) {
			rewrite ^(.+)$ /index.php?q=$1 last;
		}
    }

    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  /home/capitoleffect.me/www$fastcgi_script_name;
    }
}

So I save that into /etc/nginx/sites-available/capitoleffect.me which now makes the file ready for use. I will need to link to the file from /etc/nginx/sites-enabled before nginx knows the file is there though.

cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/capitoleffect.me

We have now finished our setup of nginx. All that is left to do is kick it into action.

/etc/init.d/nginx start

4) Compiling PHP with PHP-FPM for sexy speedy web serving

Sexy might be a little too strong to describe this, then again it is AWESOME. I've added a couple of things here like --with-xsl, --with-curl and --with-jpeg. Also I'm not sure the --with-jpeg flag is actually needed. The --with-jpeg-dir definitely is though. Let's get to it!

cd /usr/local/src
wget http://pl2.php.net/get/php-5.2.11.tar.gz/from/pl.php.net/mirror
tar zxvf php-5.2.11.tar.gz
wget http://php-fpm.org/downloads/php-5.2.11-fpm-0.5.13.diff.gz
gzip -cd php-5.2.11-fpm-0.5.13.diff.gz | patch -d php-5.2.11 -p1
cd php-5.2.11
./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --with-openssl --with-mysql --with-mysql-sock --with-gd --without-sqlite --disable-pdo --disable-reflection --with-xsl --with-curl --with-jpeg --with-jpeg-dir=/usr/lib
make all install
strip /usr/local/bin/php-cgi

We now need to update the User and Group that we want our PHP-FPM processes to run as. Open /usr/local/etc/php-fpm.conf. Find the following fields (some are in there twice) and alter the value to www-data.

<value name="owner">www-data</value>
<value name="group">www-data</value>
<value name="user">www-data</value>

Finally let's kickstart PHP-FPM into action so we can start serving PHP pages.

php-fpm start

If you want to make sure it's running place a file in the web directory we made earlier /home/capitoleffect.me/www/test.php and insert the following into the file.

<?php phpinfo(); ?>

Navigate to http://capitoleffect.me/test.php to test that PHP is running properly.

5) phpMyAdmin and migrating databases

Now that we know PHP is working with nginx we need to get the databases in order and WordPress migrated from the old server. I'm not really up on the play with using MySQL from the terminal so I prefer to use phpMyAdmin. I'm not going to go into details here as installing phpMyAdmin isn't hard if you follow the docs. Just install it somewhere on the server and either link it to an existing web directory or make a site declaration for it in nginx.

Once phpMyAdmin is up and running make a beeline for the Permissions tab on the main screen. You should be logged in to phpMyAdmin with the root mysql user at the moment by the way. Once at the Permissions page make a new user and grant them permissions on a new database.

The next step requires taking a SQL backup of the WordPress database on your old server and importing it into the new one. Export the script and we'll just make a couple of very small find and replace changes on it. We need to alter any reference to the old server folder structure (if it has changed) to whatever works in the new server. Once that is complete all we need to do is import the SQL backup into our newly created database on the new server.

6) Migrating the WordPress data

The next step is to backup the wp-config.php and wp-content/* data from the old server and to copy it over to the new server. We'll leave that to sit for a second while we go get the WordPress files fresh from the release archive.

The whole piece below is off the top of my head so it could be wrong.. especially that mv command. The better option would be to delete the www folder (if doesn't have anything critical in it, mv it if you prefer) then untar the WordPress archive to a folder called www. Either way you get the picture of what I'm trying to do here.

cd /home/capitoleffect.me/www
wget http://wordpress.org/wordpress-2.9.tar.gz
tar -xvf wordpress-2.9.tar.gz
mv -R wordpress/* ./*

Once you have the WordPress files in place we need to extract the files we backed up from the old server. Namely this should be the wp-config.php file and the files from wp-content. We need to update the wp-config.php file with our new database login details. Now the only thing left to do is change the owner of all the content we've just placed on the server.

chown -R www-data:www-data /home/capitoleffect.me

Browsing to http://capitoleffect.me should now bring up the WordPress instance all nice and dandy :)!

7) Final touches, CDN Tools+WP Super Cache

If you really want your service to purr I suggest you avail yourself of the CDN Tools and WP Super Cache WordPress plugins. Both work sweet as and as far as I've seen don't require any special setup.

At the start I mentioned CDN Tools would have an edge if hosted on a Rackspace Cloud - Cloud Server. This is because in the plugin you can tick a box which says you are on the same internal network. This will refer all internal upload traffic (from WordPress to Cloud Files) through the internal Rackspace Cloud network meaning you don't get charged extra and it's possibly faster ;)!

WP Super Cache is awesome and a recommended tool for anyone who hosts high volume WordPress sites. I've added it just for good measure but the serious lack of hits I get here means it's probably not that big of an issue for me.

So there you have it...

My two cents on setting up a cheap reliable and fast server for using with WordPress. I would love to test out how this goes with larger blogs at some point but for now I'll have to suffice with knowing that I'm dropping page render speeds from 1.5secs down to .3secs on average :)!

Filed under: The Business Comments Off
Comments (5) Trackbacks (0)
  1. That’s a lot of time shaved off!

    WP Super Cache and CDN Tools huh…. maybe I should use Super Cache sometime soon, seeing that I’m hosting quite a few blogs now. Thanks for the heads-up!

    And man, I want that Mighty Angus burger… *feels hungry now*

  2. NGINX!!!! This is great, and I will probably use it later XD Man, the combo of CDN and WP super cache is a sound idea. Rawr, think I need to upgrade my distro too >_>

    /starving

    • Hehe I had fun doing it :) I’m sure I’ll continue to find it useful. CDN Tools has been a great find and sideloading just makes sense. Super Cache makes sense with nginx as well owing to the awesome HTML serving. All around this seems like a good plan.

      All up the process is easier to do when migrating from an existing nginx setup of course but even from scratch the learning curve isn’t steep. Also lulz upgrades and my sister made muffins and tea (chai + honey).

Trackbacks are disabled.