Moving your WordPress blog from Apache to Cherokee in 30 minutes

In my post on VPS Hosting experiences, I had mentioned that inspite of doing server configuration tweaking, I found that load times were gradually increasing and I was experimenting with an alternative server named Cherokee.

The whole migration took less than half a day – including learning Cherokee, trying out locally and then using it in my blog. So what are the steps I followed to move to Cherokee?

I use Ubuntu 10.04 LTS as my dev system as well as on the production server – so one of the things that I am confident about is that, if something works in my dev environment, it is bound to work in the production setup, with minimal pains during deployment. So I wanted to first try out the entire setup – make sure everything is fine, and then replicate the setup on the production server.

I started by installing Cherokee from the PPA and also php5-cgi:

add-apt-repository ppa:cherokee-webserver/ppa
apt-get update
apt-get install cherokee
apt-get install php5-cgi

The next thing I did was to set buzypi.in in /etc/hosts to point to my dev system:

12:12:24:~ $ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 ananya
127.0.1.1 buzypi.in
...
12:12:24:~ $

I then installed my WordPress blog in my dev system using Apache, so that I could go to http://buzypi.in/ and it would actually render the blog from my dev system.

Once this worked, my sandbox was ready for experimentation!

I stopped Apache and started Cherokee. Also, I started the cherokee-admin process and logged into the admin console.

12:20:11:~ $ sudo /etc/init.d/apache2 stop
* Stopping web server apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
... waiting [ OK ]
12:20:28:~ $ sudo /etc/init.d/cherokee start
Starting cherokee web server
12:20:32:~ $ sudo cherokee-admin

The first thing to do is to create a VServer entry to point to the deploy directory. This is the easy part – and you wouldn’t run into any issues if you follow the Cherokee documentation.

The more difficult part is in setting up behavior rules. A large part of the half-day spent in the migration was in figuring this out. Behavior rules are similar to the Apache rewrite configurations. However there are subtle differences between the 2 and it took me a while to figure out the exact rules required.

Also, to make things a little more complex, I have 2 WordPress blogs hosted in production – one is at http://buzypi.in/ while the other is at http://payaniga.in/blog/, so the behavior rules would be different for the 2.

The default out-of-the-box WordPress recipe didn’t seem to work – so I had to create one manually.

Finally, here is the configuration that worked:

For buzypi.in

This configuration is for a website where the root is the WordPress blog.

Have 4 behavior-rules:

Rule 1

Rule
Rule Type: Extensions
Extensions: php

Handler
Handler: FastCGI

Rule 2

Rule
Rule Type: Regular Expression
Regular Expression: /(.+)

AND

Rule Type: File Exists
Match any file: Enabled
Only match files: Enabled
If dir, check index files: Enabled

Handler
Handler: List & Send

Time to expire: 1w

Rule 3

Rule
Rule: Regular Expression
Regular Expression: /(.+)

Handler
Handler: Redirection
Type: Internal
Regular Expression: [leave blank]
Substitution: /index.php?/$1

Time to expire: 1d

Rule 4

Default
Handler: List & Send

For payaniga.in/blog

This configuration is for a website where the root is some independent page and the WordPress blog is at a different location.

Rule 1

FastCGI handler configuration as above

Rule 2

Rule
Rule Type: Regular Expression
Regular Expression: /blog/(.+)

AND

Rule Type: File Exists
Match any file: Enabled
Only match files: Enabled
If dir, check index files: Enabled

Handler
Handler: List & Send

Rule 3

Rule
Rule: Regular Expression
Regular Expression: /blog/(.+)

Handler
Handler: Redirection
Type: Internal
Regular Expression: [leave blank]
Substitution: /blog/index.php?/$1

Rule 4

Default as above

Handling redirects from www.host.com to host.com

In order to redirect www.buzypi.in to buzypi.in, we need a separate VServer for www.buzypi.in.

Here, just add a new rule (remember to replace buzypi.in with your own hostname):

Rule
Rule Type: Header
Header: Host
Type: Matches a Regular Expression
Regular Expression: buzypi.in

Handler
Handler: Redirection
Type: External
Regular Expression: /(.*)$
Substitution: http://buzypi.in/$1

Now here is the sweet part:
Once I added these configurations, I just had to test the configuration to make sure things are fine. Once I saw that the configuration was fine, all I had to do was to install Cherokee on the production server as before, but I didn’t have to make any of the configurations. Instead, all I did was to copy /etc/cherokee/cherokee.conf from my dev system to the same location on the production system and it worked as if nothing had changed!

It has been close to a couple of months now, and the load times are amazing compared to Apache. Here is a screenshot from Google Webmaster Central:

 



 

The first dip you see in Feb was after tweaking the configurations in Apache – the second dip was after migration to Cherokee. As you can see, the load times have been pretty consistent and has seldom crossed the 550ms mark.

Thanks to Madhukar Pai for all the pointers during migration.

Update (21 Apr, 10:30pm): Did I speak too fast? I am seeing quite a few Gateway Timeout errors after this post received a little fame in the webs. A restart of the server helped – but I intend to do some load testing and publish the results soon. I still feel Cherokee is way better than Apache in terms of resource usage.

Update (Jul 3):
I imported all photos from Flickr to my website since my Flickr account expired. It has been close to a month, and it looks like the server is coping up without any issues.

13 Comments

  1. Thanks for the credit.. :) How has the load been on the VPS? Have you seen any improvements? You think you could squeeze more out of the very base VPS?

  2. Well, the load was never a problem, the memory was and with Cherokee, I see an improvement in memory consumption and it is hardly using swap. Right now, I am using the default configuration of Cherokee – I am sure there is scope to tweak it.

  3. you don’t need a different virtual server to handle www traffic. Just go into host match, and set it at wild card, then add a entry for example.com and http://www.example.com your site will work either way they try to access it.

  4. Thanks Dustin, will try this config.

  5. Hi…

    I’m also running a Cherokee server on a small Ubuntu 10.04 VPS (just 512 MB RAM) and it works pretty well… most of the time: I too received random Gateway Timeout errors from time to time.

    Doing a little research, I found that this weren’t actually Cherokee errors, but instead they were bugs in the PHP FastCGI process, which actually doesn’t die but just stop responding… so it’s a real pain to try to fix it

    Actually, I’m yet to find a real solution to this issue, but from what I saw elsewhere it seems that one of the most practical solutions (probably not the best, but easy to implement and useful) it’s to monitor the PHP FastCGI process itself. I’m currently doing it with a bash script (must have curl installed) that you can check on https://gist.github.com/952694

    (obviously, replace http://www.yukei.net with your own URL)

    Basically, what it does it’s to send a request to the given URL and if a 504 HTTP header is found, kill the php-cgi process and get it up again with spawn-fcgi

    … As I said before, probably not the best solution (but it works)

  6. Hello Felipe,

    That will save me some debug time – thanks.

    I have a couple of issues with your script though – I have additional parameters that I send to php-cgi, specifically, memory_limit. I am not sure if I need to pass it explicitly or it will read from php.ini. Also, how do we know how many php-cgi processes to spawn?

    I will need to investigate this solution and if there is a cleaner way to implement it – the best thing would be to get it fixed in fastcgi.

  7. My suggestion is to set a relatively low value for the maximum number of requests to serve with one FCGI instance, ’cause PHP and Python scripts tend to have memory problems in the long run.

    Regarding the number of processes to spawn, it really depends on how much RAM you have free and how much RAM each spawn eats on average.

    E.g. I have 100 MiB RAM free on average, and on average each of my php-cgi processes eats up 30 MiB. I shouldn’t have more than 3 running at the same time.

  8. That’s some good advice.

    Thanks NeXus.

  9. You could have tried Varnish on Apache.. :)

  10. I actually tried Memcached and it made the memory problems worse, so I decided to try Cherokee – as I read that the memory consumption is lower.

    I didn’t try Varnish – may be I could run some tests to see how the 2 compare.

  11. Great article! After wasting half a day on playing with WordPress and Cherokee, I wish this had come up in my many Google searches! Once I get it to work, I’ll make sure to blog about you so others will find this.

    How would you modify these rules so that your site can be viewed from example.com while the wordpress files exist in example.com/wordpress/

    see: http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory

  12. Oh, one last question, Can you publish a Cherokee config file for these settings? I’ve had nothing but trouble with the “easy” admin interface. I’m great with config files but the Cherokee file is a mess and all the WP documentation uses the GUI.

  13. Hello Greg,

    You are referring to the setting that I have at http://buzypi.in/.

    Just follow the buzypi.in settings above, and in your WP General Settings set the WordPress address (URL) to http://example.com/wordpress, assuming wordpress is your wordpress directory and Site address (URL) to http://example.com.

    I will publish my config soon – but frankly, the Cherokee config file looks very cryptic. I wish they had used XML.

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>