Nginx, pronounced “Engine X,” is a high performance HTTP server and reverse proxy that is also able to proxy IMAP and POP3. Written by Igor Sysoev and licensed under a BSD variant, the official site is here.
While most of the official site and documentation is in Russian, an English language wiki is available. Nginx has a modular architecture and can serve static content extremely quickly using a high number of concurrent connections. It does accelerated reverse proxying without caching.
If a caching web accelerator is more what you’re looking for, you might look into Varnish, which we covered recently. (See Getting Glossy with Varnish.) Additional HTTP features include simple load balancing, fault tolerance, ACLs, flexible rewriting, FastCGI, and SSL.
Nginx also supports a variety of mail proxy features such as user redirection to IMAP/POP3 backends using an external HTTP authentication server, user authentication using an external HTTP authentication server, SSL, STARTTLS, and STLS. The mail proxy functionality is used in some very high volume implementations, including FastMail.FM and Zimbra.
Setting Up Nginx
Let’s get started with Nginx. After you download the latest tarball from the Nginx site, you can install nginx as follows:
$ ./configure --user=daemon --group=daemon && make
# make install
You’ll need to adjust the configuration flags depending on the functionality you plan on utilizing. For instance, if you’d like to use regular expressions in your configuration file, you’ll need to point configure to the PCRE library.
The default installation path for nginx is /usr/local/nginx. With nginx installed, it’s time to create a configuration file (default: /usr/local/nginx/conf/nginx.conf). This configuration file will serve static content for a single virtual host:
worker_processes 2;
pid/var/run/nginx.pid;
error_loglogs/error.log info;
events {
worker_connections 1024;
use epoll;
}
http {
includeconf/mime.types;
default_typeapplication/octet-stream;
sendfileon;
gzipon;
gzip_comp_level5;
gzip_typestext/html text/plain txt/xml text/css application/x-javascript;
server {
listen80;
server_namewww.domain1.com;
access_loglogs/domain1.access.log main;
location / {
indexindex.html;
root/var/www/domain1.com/htdocs;
}
}
}
You can use a regular expression along with the deny directive to block access to all subversion directories.
location ~ /.svn {
deny all;
}
You may want to serve all images with Expires and Cache-Control headers that will allow caching at the browser level, while not clogging the access log.
location ~* ^.+.(jpg|jpeg|gif|png|)$ {
access_log off;
expires 30d;
}
To perform simple load balancing between three servers, one of which is more powerful. This will allow you to do that:
upstream my_cluster {
server 192.168.1.1 weight=3
server 192.168.1.2
server 192.168.1.3
}
server {
listen 80;
server_namewww.domain.com;
access_log logs/www.domain.access.log main;
location / {
proxy_passhttp://my_cluster;
proxy_set_headerHost $host;
proxy_set_headerX-Real-IP $remote_addr;
proxy_set_headerHostX-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Once you’ve finalized your configuration, you should test the syntax with nginx -t. You’re now ready to start serving content. Don’t forget to add nginx to your startup scripts. One nice feature of nginx is that you can upgrade to a new binary without losing a single incoming request.
To accomplish this, replace the old nginx binary with a new one. Then send a USR2 signal to the nginx master process, which will rename its C<.pid> file to .oldbin and then execute the new binary. You can now phase out the old binary by sending its master process a WINCH signal. Once all old worker process are done you can send the old master process a QUIT.
Nginx allows you to quickly and easily serve static content, while giving you the flexibility to proxy dynamic content and other requests to any number of backends. If you have a rapidly growing site, its small memory footprint, secure code and high concurrency could be a welcome addition to your infrastructure.
Amazing. Thanks Jeremy!
Just one question: How does this compare to lighttpd?
I don’t know about recently, but lighttpd suffered some leakiness a while back (which is in part why nginx became so popular). I’ve tested nginx for static content and even on smaller servers concurrency+requests I can max out the ethernet without the server hiccuping (this is a dual quad-core Xeon X5355). It simply doesn’t run out of power and easily overpowers Apache for anything static. It’s clumsy on PHP, but Apache is awful on Rails, so it’s a choice of poison. One factor not mentioned here is nginx has Flash streaming available in the binary and some pretty slick stats are possible using rrdtool, and of course gzip compression is available. It’s extremely small, extremely simple to configure, and I’ve never been able to crash it in comparable tests against Apache where Apache ran through all memory and then began to fail. If you’re running Rails, you’ll probably want to run nginx (the dev version 0.6.30 is just as stable in my tests as the “stable” version FYI). I noticed even CNN is using it for their politics blog. I can’t recommend it highly enough, and I’ve been configuring webservers from scratch for almost 15yrs.
I’m not sure about generic performance ratings, but I know for a fact that Nginx is very popular in the Ruby on Rails world (used as a HTTP server/proxy/load balancer) and also serves several high traffic sites. Ezra of EngineYard has written several blog posts related to Nginx.
Sorry I couldn’t find the actual benchmarks, but as far as I remember Nginx outperformed everything in Rails cases. Nginxs’ ability to use Unix domain sockets also has been out to use.