Nginx reduces page load time, increases Googlebot activity

nginx logoAfter a small incident with a shared host, I moved my phpBB forum and a few other static sites to a VPS running on nginx. Nginx is a small, lightweight but very efficient web server created by Igor Sysoev, originally developed for www.rambler.ru, Russia’s second-largest web site. Due to it’s light-weightedness and efficiency, it is used by a lot of high traffic sites like WordPress, Hulu, Github, Ohloh, SourceForge, TorrentReactor, etc. After moving to Nginx, I noticed a significant improvement in page load times. The pages on the site load in around 0.0X seconds now, as reported by the phpBB’s measurement system. The pages also seem to be snappier as compared to the time when I was on Litespeed.

I recently noticed that apart for the decrease in page loading time, the activity of Googlebot has increased manyfold. Here’s a screen-shot of the report from Google Webmaster Tools :

Google Webmaster Tools NginxNot bad, eh?

More recently, I moved this blog to the VPS running on Nginx, and I have not been disappointed. This blog is running on WordPress 3.0.1, with no caching plugins. The posts seem to load faster than ever, as evident from this Google Webmaster Tools report :

google webmaster tools nginx techtitbits

I couldn’t be more happy.

PS: Of course, some of the speed improvement can be attributed to the fact that I moved from a shared server to a VPS, but that doesn’t undermine the awesomeness that is Nginx.

Enable directory listing in nginx

nginx logoEnabling directory listing in a folder in nginx seems simple enough with just an autoindex on; directive inside the location directive. However, for some reason, it didn’t work for me.

I finally got it to work by moving the root directive out of location.
So, if you have something like this :

[code]server {
listen 80;
server_name domain.com www.domain.com;
access_log /var/………………………;
location / {
root /path/to/root;
index index.php index.html index.htm;
}
location /somedir {
autoindex on;
}
}[/code]

Change it to :

[code]server {
listen 80;
server_name domain.com www.domain.com;
access_log /var/………………………;
root /path/to/root;
location / {
index index.php index.html index.htm;
}
location /somedir {
autoindex on;
}
}[/code]

Directory indices should show flawlessly now.
(A live example can be found here.)

Www/no-www rewrite rules for nginx

nginx logoThere are many ways to rewrite www urls to their non-www versions in nginx. Here one that’s Igor-approved and works well on my setup :

WWW to Non-WWW:

[code]#301 redirect www to non-www
server {
listen [::]:80;
server_name www.domain.com;
rewrite ^ http://domain.com$request_uri? permanent;
}
server {
listen [::]:80;
server_name domain.com;
…………………………………..
…………………………………..
}[/code]

Non-WWW to WWW:

[code]#301 redirect non-www to www
server {
listen [::]:80;
server_name domain.com;
rewrite ^ http://www.domain.com$request_uri? permanent;
}
server {
listen [::]:80;
server_name www.domain.com;
…………………………………..
…………………………………..
}[/code]

Unexpected email and Alexa bot

I got a surprise today when I found that I have an email in my inbox from webmaster@animorphsfanforum.com. The email had subject “Subject” and has content “Content”. My first instinct was that someone has hacked into my VPS. After a few minutes of mind-racking, I remembered that I had created a PHP file on the VPS named ‘mail.php’ to test whether emails were being sent. But, no one knew of it’s existence except me. Someone must’ve stumbled upon it my chance.

I logged into my VPS and checked the access logs.
[bash]cat animorphsfanforum.access.log | grep ‘mail.php'[/bash]
[code]174.129.237.157 – – [20/Jul/2010:05:32:40 +0000] "GET /mail.php HTTP/1.0" 200 0 "-" "ia_archiver (+http://www.alexa.com/site/help/webmasters; crawler@alexa.com)"[/code]

I have a Firefox plugin to check the Alexa rank, and the URL must’ve been sent to Alexa when I executed that script for the first time. The Alexa bot sent the email while crawling the URL.

Much ado about nothing?

Nginx: Resolving “No input file specified” error

nginx logoIf you are using nginx with php-cgi and have followed the standard procedure to set it up, you might often get the “No input file specified.” error. What happens here is that, when nginx receives the request to serve a non-existent php file, it passes the request to php-cgi. Php-cgi, while trying to processs the request, finds that the php file does not exist at all. Hence it sends a “No input file specified.” message with a “404 Not Found” header.

Although, it’s not technically an error, we can catch the request for the non-existent php file and show a custom 404 page.

First, find out the version of nginx you are using.

[code language=”bash”]nginx -V[/code]

You’ll get an output like this :

[code language=”bash”]nginx version: nginx/0.7.65
TLS SNI support enabled
configure arguments: –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –pid-path=/var/run/nginx.pid –lock-path=/var/lock/nginx.lock –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/var/lib/nginx/body –http-proxy-temp-path=/var/lib/nginx/proxy –http-fastcgi-temp-path=/var/lib/nginx/fastcgi –with-debug –with-http_stub_status_module –with-http_flv_module –with-http_ssl_module –with-http_dav_module –with-http_gzip_static_module –with-http_realip_module –with-mail –with-mail_ssl_module –with-ipv6 –add-module=/build/buildd-nginx_0.7.65-2~bpo50+1-i386-1taiV6/nginx-0.7.65/modules/nginx-upstream-fair[/code]

If php-cgi is running on port 9000, you’ll have something like this in your vhosts file :

[code]location ~ \.php$ {
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME ….
……………………………..
……………………………..
}[/code]

Since nginx versions less than 0.6.36 doesn’t have the try_files directive, we’ll have two versions of the code.

For nginx 0.6.36+
We’ll use try_files here to catch and display an error page.

[code]location ~ \.php$ {
try_files $uri /path/to/404.htm;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME ….
……………………………..
……………………………..
}[/code]

For older versions :

[code language=”bash”]location ~ \.php$ {
fastcgi_intercept_errors on;
error_page 404 /path/to/404.htm;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME ….
……………………………..
……………………………..
}[/code]

This will display the chosen 404 page for non-existent php files instead of the unhelpful “No input file specified.” message.