WordPress runs on something knows as an AMP (Apache, MySQL, PHP) stack. Apache is your web server software. MySQL is your database engine. And PHP is the language WordPress is written in. Out of these three, the web server is the only component that you can replace with something else. Most people use Apache just because it’s very simple to set up — and that WordPress supports it out of the box. But what if you could tweak around and install another web server that is immensely faster than Apache?
Enter Nginx. Pronounced Engine X (Engine 10), this web server software was created by a Russian developer to solve something known as the C10K problem. Most traditional Web servers (Apache included) uses threads to serve each request. I know this is kind of technical, but you’ll see — creating new threads is a very expensive operation for operating systems, and there’s a limit to the number of threads that can can be spawned. As such, the theoretical limit for Apache is 10,000 concurrent connections.
Nginx is a breed of new Web servers that use an event-driven technique to Web serving. Jobs are performed asynchronously (which basically means that tasks are executed in parallel, and that one task doesn’t have to complete for the next to commence) — which makes it immensely fast. Every new connection uses a small, and more importantly predictable amount of memory. The end result? A fast Web server which uses very less memory, and can serve more than 10,000 connections concurrently.
‘Nuff said.
Will WordPress Like Nginx?
Good question. One of WordPress’s quirks is that it uses files named .htaccess
(which is an Apache-specific feature) which are used to control redirections if you use pretty permalinks. If you don’t use pretty permalinks (e.g., your blog has links like www.myblog.com/index.php?p=100&d=200
) then you’re pretty much set. If you do use pretty permalinks, (like www.myblog.com/2011/01/01/happy-new-year.html
) then you’ll need some additional configuration (which I’m going to show you here).
Now there’s another problem. WordPress is very extensible, which means it supports plugins. WordPress itself doesn’t rely much on .htaccess
files other than to handle redirections, but plugins may use it to handle access-control and permissions. Now the list of such plugins is infinitesimally small, and any such plugin which uses .htaccess
files is badly designed anyway, since plugins shouldn’t make assumptions about the Web server its running under, but if you must use those plugins, then you’ll either have to do without the access-control (you can chmod
the files appropriately), or you’ll have to do without Nginx.
Us? We still aren’t big enough to warrant moving to VPS, so we use whatever server out hosting provider provides. But here’s some trivia for you — WordPress.com itself runs on Nginx.
Getting Started
I’m assuming you’ve got a VPS with Apache, MySQL and PHP already hosting your blog. What we’ll do is install Nginx and the PHP connector, and switch the site over from Apache to Nginx in a single step that will typically involve less than a second of downtime.
Most servers run either Debian/Ubuntu Server or RHEL/CentOS. If you’re one of the lucky ones to afford SUSE Linux Enterprise, you’ll have to figure out how to install Nginx yourself.
Nginx development takes place very fast. For this reason, your distribution binaries are generally going to be way out of date. But there’s a way out — Nginx provides official repositories (yes, complete repos, not just binaries) for many operating systems.
If you run Debian Squeeze, add these lines to your /etc/apt/sources.list
:
deb http://nginx.org/packages/debian/ squeeze nginx deb-src http://nginx.org/packages/debian/ squeeze nginx
If you run Ubuntu Server, the lines for /etc/apt/sources.list
are:
deb http://nginx.org/packages/ubuntu/ lucid nginx deb-src http://nginx.org/packages/ubuntu/ lucid nginx
Needless to say, you should be running the LTS version of Ubuntu Server. Nginx also has official versions for RHEL and CentOS. To add their Yum repo, create a new repo file at /etc/yum.repos.d/nginx.repo with the contents (for CentOS):
[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=0 enabled=1
And for RHEL:
[nginx] name=nginx repo baseurl=http://nginx.org/packages/rhel/$releasever/$basearch/ gpgcheck=0 enabled=1
Now you can install Nginx using your package manager. For Debian/Ubuntu, run:
sudo apt-get update && sudo apt-get install nginx
You’ll get Certificate errors for Nginx because apt
does not automatically add certificates for repositories. The certificate links are in the Appendix section at the end of this article. Anyway, for RHEL/CentOS, run:
sudo yum install nginx
You now have Nginx. You’ll have to install the PHP FastCGI connector now.
You’ll need to add a repository if you’re on Debian Squeeze. Add these lines to the /etc/sources.list
file:
deb http://packages.dotdeb.org stable all deb-src http://packages.dotdeb.org stable all
You’ll also need to add a repository if you’re on RHEL/CentOS 5. Run the following commands:
sudo rpm -Uvh http://repo.webtatic.com/yum/centos/5/latest.rpm sudo yum --enablerepo=webtatic update
Now, to install, on Debian/Ubuntu type:
sudo apt-get update && sudo apt-get dist-upgrade sudo apt-get install php5-fpm
And on CentOS/RHEL, type:
sudo yum --enablerepo=webtatic install php-fpm
You’re officially on the road. All you need to do now is configure Nginx, start php-fpm
, and then in one step stop Apache and start Nginx.
Configuring Nginx
I’m assuming your Webroot is at /var/www
. If not, adjust the following file appropriately. Open up the file /etc/nginx/sites-available/default
, and replace everything in there with the following:
server { listen 192.168.1.1:80; # Your server's public IP address server_name example.com; # Your domain name root /var/www/; # Absolute path to your WordPress installation try_files $uri $uri/ /index.php; # Handle permalinks if (!-e $request_filename) { rewrite ^.*$ /index.php last; # More code to handle permalinks } # This is what the HTACCESS is basically for location ~ \.php$ { include fastcgi_params; fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }
That’s it. Now, we’ve got to start php-fpm
, by doing:
sudo /etc/init.d/php-fpm start
And then in one fell swoop, switch the Web server:
sudo /etc/init.d/httpd stop && sudo /etc/init.d/nginx restart
Don’t worry about the restart thing in the last command — some ditributions think its really cool to start nginx on port 8000 as soon as is it’s installed.
Now access your site. Happy?
You can now go ahead and remove all Apache packages from your system. That should be it. Oh, you should go ahead and install this plugin.
What If It Doesn’t Work?
Leave Comment below, and we’ll help you out.
Appendix: Certificates For Debian/Ubuntu
To add the DotDeb certificate, do:
wget http://www.dotdeb.org/dotdeb.gpg cat dotdeb.gpg | sudo apt-key add -
And to add the Nginx certificate, do:
gpg --recv-key 7BD9BF62 gpg --armor --export 7BD9BF62 | sudo apt-key add -
The reason NginX is faster than Apache as explained in this post is not taken. Running threads parallely is not the property of a thread but that on the system on which the threads are working. Threads do run parallely and do not have to wait for each other to get completed
@arnie41178 1) Threads do run in parallel, but for four cores and 10,000 connections, that’s 2500 context switches per core.
2) If you’ve ever done asynchronous programming, you’ll know. If not, asynchronous programming relies on triggers and callbacks. There are multiple threads, like about 20-25, and they all form something called a thread pool. A task (like serving that webpage) is created and delegated to a thread from the pool. Once the task finishes, it fires the callback to let the main server know that its done, but the main server continues its work as soon as the delegate is created and pushed out to a thread in the pool. New threads aren’t spawned for every task – the threads are always there. And there are just one hundredth of the number of threads compared to a normal server.
@baloney: thanx point clarified
[…] https://www.opensourceforu.com/2011/12/supercharge-wordpress-with-nginx-fastcgi/ Leave a Comment TrackBack URI […]
Thanks alot for this short, but powerful tutorial. You just saved me from an embarrassment from a client running a memory-hungry “wordpress” blog.
Before the thing could work on my Ubuntu 12, I had to do some tweaking.
1. /etc/nginx/sites-available/ was not included in my configuration file. So I added a line with “Include /etc/nginx/sites-available/*;” to “/etc/nginx/nginx.conf” file.
2. An index file “index.php” was not specified in the default confuguration so the index of the site didn’t work until I embedded the following in the server { } of “/etc/nginx/sites-available/default” file.
location / {
index index.html index.htm index.php;
}
It now works like a charm!