Nginx runs all my Rails sites and will forever. If you haven't tried it yet, I can't say enough good things about it. It never breaks. It has just absurdly good memory consumption, which is clutch when you're trying to run your site on a memory heavy platform like Rails on a VPS which is very memory constrained.
(By comparison, Apache is quite the memory hog and I still haven't figured out how to say the magic words to get it to not effectively crash my blog and every other site on the server if I burst to 10,000 visitors in an hour. That is not supposed to be a big number. Apache has 500 MB to play with and still can't keep up.)
I also find, and this might just be a matter of taste, that the configuration makes more sense to me than Apache configuration does. This is funny because Apache configuration is obsessively well-documented and Nginx configuration is not.
Additionally, some easy-to-use features cover weak points in typical Rails (&etc) deployment scenarios. The big one for me is file serving, since my website is essentially one big PDF printing press. The simplest level (works for me, won't work for Facebook) is just having the file anywhere accessible on the disk and having the application put a special header on the response saying "Hey, Nginx: give them this path.", then terminating Rails' involvement. That frees up your Mongrel to start doing hard work again and greatly, greatly, GREATLY decreases the resources you need to stream your 5 MB PDF, 20 MB executable, etc to the user.
So it scales down, but does it scale up? Ooooooooh yeah. Impressively so. See the tales of Wordpress deployment, where not a whole lot of Nginx gets hit with a year's worth of my traffic every couple of seconds and still keeps on trucking.
I use nginx+passenger and love the heck out of it. Trivial to set up, blazing fast, rock solid, and easy to administrate. I've switched away from Apache for everything except my dev server, and haven't looked back.
I experimented with Nginx + passenger and had little success in the time I had budgeted that weekend (almost certainly due to my own failings). That is my max geekout budget. After that I have to have a reason to rip out stuff and I've got no compelling reason to rip out Mongrel (nota bene: I typically deploy only one or two Rails applications per VPS, with the expectation that they'll essentially monopolize resource usage. If my deployments resembled that of a shared host who could have ~600 forgotten Build A Blog In 15 Minutes apps sitting around waiting for someone to access them again, I'd have figured out Passenger by now or paid someone to figure it out for me.)
How long ago did you try it? I think I started using passenger in the past....3 months? The version of install-passenger-nginx-module I used would compile your nginx for you, and set up the configuration. You just have to change the path to your public directory.
I found the main benefit of Passenger in a single-app setting is (much) easier initial setup.
Give it a try next time you set up a server. It'll save you about 30 minutes to an hour of screwing around with mongrel cluster configs and nginx proxying.
Passenger is worth figuring out, especially if you plan to do more Rack apps in the future. Forget the performance. It's easier to set up (at least, the second time) and it's easier to manage.
We've been using nginx at engine yard for 4 years now and I can say that it is the most solid peice of software out of the hundreds of open source componenets we run. We have close to 15k nginx dEmons running if not more last I counted and it accounts for 0.001% of production issues/problems.
Can't say enough good things about this peice of software. It just works and it's smoking fast and very resource friendly. Thumbs up all around
Ezra, you deserve a lot of the credit for the growth of Nginx. Your evangelism has done nothing short of catapulting its exposure in the community. So, thank you.
Thank you, I just looked back in time and it seems I started playing with nginx in 2006. Here was my first blog post whee I figured out how to run rails with it.
Nginx is incredible. It's my second favorite piece of software (haproxy wins by a hair). At justin.tv we serve tens of billions of requests per month using nginx, and it uses so few system resources that we can run our CPU-heavy caching engine on the same servers.
Take a look at the source sometime. It's kind of fun to see an HTTP parser written like, "if (ngx_str3_cmp(m, 'G', 'E', 'T', ' ')) { r->method = NGX_HTTP_GET;"
I've absolutely loved patching and working on modules for nginx source code. Partially I suspect because it's so homogeneous. It's nice and modular and succinct - the optimizations don't obfuscate the code. As others have pointed out, responding to http requests is not rocket science, and digging into nginx reminds you that responding to a simple problem simply tends to yield pretty good reliability and performance.
Good to hear you would recommend Nginx. Would you mind expanding on how you use Nginx and haproxy together ? Do you front haproxy with Nginx or vice-versa ?
Duck Duck Go uses nginx. I evaluated all the alternatives pretty heavily, and it was the clear winner at the time (2 years ago). I currently use the memached plugin, which is great. I've also used its embedded Perl feature (though not currently).
I've been touting nginx to anyone who will listen here and elsewhere for 2+ years. It just never breaks. Billions and billions of requests, no problem. Spikes up to 500 Mbps, no problem. DOS attacks, misconfigurations, exotic in-a-pinch config changes (think: had to throw in a quick 100K URL map via the hash system), no problem. And the relatively small servers we run it on just putt away nearly idle. It's just too good.
Pingdom: Where do you think nginx will be in 5 years?
Sysoev: I really have no idea.
Although this statement sounded negative at first, it is actually brilliant. Rather than defining a cast-in-stone development plan, focus on what the market is going to be asking from you as you go along and code it.
Well, nginx started because Apache devs didn't want to address the issue that arised when lots of users with slow connections were accessing the site. Anyone else remember the Slowloris HTTP DoS - ngingx is basically immune to it...
As Sysoev was working for one of the Russia's biggest portals that apache couldn't handle very well.. So he wrote a server that did one thing very well - waits until client submits their request and then serves this request as fast as possible. And he did it well :)
Nginx got mentioned in printed books, mostly Ruby on Rails related.
I'm proud to say I contributed to this. From RailsSpace (2007), p. 506:
Nowadays, it seems that many of the cool kids have switched
to a webserver called Nginx, used on its own or as a proxy
server. Since much of its documentation is in Russian,
Nginx (pronounced "engine X") is relatively obscure, but
we've heard great things about it, and it's currently being
used by several prominent Rails hosting companies.
Everything in the quote is still true---except for the "obscure" part. :-)
I would disagree. Much of the documentation has been translated to English, with miscellaneous bits of information also available through sites such as StackOverflow and ServerFault.
That said, compliments on spotting a solid piece of software from a mile away.
Coming up next are [...] probably new embedded languages: Javascript or Lua.
This is interesting. On Sysoev's personal website, there is an article "Why Google V8 is not suitable for embedding into a server yet"(Russian) http://sysoev.ru/prog/v8.html
Basically, he's saying that V8 was developed with Google Chrome in mind, so it's not an easy task to embed it with any other software. The main point is, V8 can't handle memory allocation errors - it just crashes the process, which is suitable for Google Chrome but not for a server.
I feel like the other point here is that writing a webserver isn't rocket science. If a webserver is very important to you, and nothing freely available really fits your use case well, just write your own.
+1 for NGINX + PHP-FPM + XCache + MySQL as a replacement for the LAMP stack - significantly decreased my web server's utilization of both CPU and Memory...
Can you detail this configuration? How easy/hard is it to setup this stack and then later maintain it? Plus, how much improvement did you actually get will be an interesting piece of info.
It's gotten a lot easier recently. I believe I installed PHP-FPM through aptitude, and nginx comes from that too. Compiling a newer version yourself isn't that hard. However maybe 2 months ago I couldn't say the same.
Also, unrelated, but I see most arguments in favor of nginx say that it is excellent at serving _static_ files. Since my application serves mostly dynamic content, what do you think can be performance benefits?
Well if you don't run your app as CGI then there might be a difference. For example using mod_php vs fastcgi or fpm (from what I hear mod_php is faster than fastcgi).
And if you host your static files on a CDN that's even less reason to use nginx.
It shows that if you just run PHP, mod_php results in better performance. So, many people who also need to serve static content use nginx for static, and then proxy PHP requests to apache (though this seems like it would defeat the purpose of needing apache).
Of course this all becomes moot if you consider that when you get to these points of performance demand you'll probably take a look at HipHop (assuming you use PHP) and compile your PHP+Web server into a single daemon.
EDIT: By the way, that linode article uses spawn-fcgi, not php-fpm. php-fpm is in the dotdeb repository and you have to add that to your sources.list.
Those benchmarks certainly back it up. Nginx in front of Apache seems like the best approach. I would like to see an optimization guide for setting up Apache to process PHP via mod_php. By comparison, I always found optimizing nginx to be far more straightforward than optimizing Apache.
On a sidenote, does it make sense to use HipHop in conjunction with xcache?
HipHop will completely invalidate your need for Xcache as you now have an executable instead of php. You can probably get away with nginx for static and proxy it to HipHop'd php for your php. But that's still overkill in most situations.
The nginx for static and php-fpm (which runs php as a fcgi) will get you very very far. Wordpress.com for example uses a similar setup (with a hell of a lot of caching in between).
Most of my apps aren't bound by php cpu time, I'd only use hiphop to play with personally. =)
Proxying to Apache for dynamic requests is still a win if you let nginx buffer the response. This local transfer is fast, which frees the apache process, and all the memory it uses, to serve the next dynamic request while nginix takes care of emptying the buffered data to the "slow" client. At the same time, you get to tap the vast knowlwge base for deploying php apps on apache.
We (at the time I was the CTO for massify.com) evaluated a lot of different configurations and nginx+php-fpm+apc was about the fastest we could get the site going.
on the maintenance side - I find NGINX conf files to be substantially easier to work with than Apache's - check out the demo conf at the end of this article for example: http://www.linuxjournal.com/article/10108 .
I love nginx, but one thing that I wish nginx could do is be able to enable/disable modules without having to recompile. It's annoying having to recompile nginx whenever a new version of passenger is released.
Here's the script I've been using to install the latest version. It was kind of quickly hacked together, and the symlink stuff near the end breaks occasionally, so if anyone's going to use this, you might want to read it over first.
It's annoying, but I'd imagine there would be a performance penalty for having dynamically loadable modules. I'd rather keep the performance, and just have to recompile.
I suspect that a lot of that is performance-oriented. By compiling modules into the binary, I suspect you can get far superior performance out of it than you could with hot-loaded modules.
Calling dynamically loaded libraries is very fast, no more than a few nanoseconds per message that passes between the server and a module. It is no worse than the dynamically-linked C standard library we use so heavily.
Development effort is probably the real reason. It takes a fair amount of planning to design a table-driven module loader and indirection layer. Indirection with raw pointers costs brain power. (And do not even think about the reference counting hell of a dynamically unloadable module.)
Edit: And think about what happens when you upgrade a Django or Rails plug-in: it generally gets recompiled and what amounts to relinked. The difference is that the language system itself hides the work, while nginx uses explicit build tools.
Given that you can hot-swap the binary you could just write a bash script to enable or disable the modules you want and swap out the binary when it finishes compiling your changes.
Also check out Cherokee - http://www.cherokee-project.com/ - has a lot of similar features as nginx (small and fast), but also has a saner development model, public SCM, a bug tracker (!!!) and a friendlier dev team.
Among the most famous sites using Cherokee are the (recently hyped) chatroulette.com and Lawrence Lessig's web properties.
I find that cherokee and lighttpd is a pain in the butt when it comes to getting ssl working, all kinds of weird problems. It's dead easy with apache. How's nginx and ssl?
Coming up next are backend interactions and cache improvements, refactoring of the rewrite module, and probably new embedded languages: Javascript or Lua.
I really hope he includes lua and javascript. Both would be cutting edge (Javascript server side is still pretty new) and Lua which should be used more. Kepler Project (http://www.keplerproject.org/) is pretty good but Lua gets no love, this could change things big time for Lua.
True, but in terms of people using it in production and some of the faster JS engines like V8, Tamarin, Spidermonkey, Rhino etc it is having a resurgence now that it is getting to fast enough.
It's in russian unfortunately... Probably google translate will help? In short - article says that V8 is not ready to be embedded in servers because of certain shortcomings.
I highly recommend Nginx. Not only does it use less resources than Apache, it is actually easier to use than Apache and Lighttpd. I found the configuration file format to be very easy to learn.
The only feature I miss from Apache is being able to use .htaccess.
.htaccess made sense in the world of spaghetti code CGI/PHP scripts running on shared servers, in the world of app frameworks like Rails and Django that stuff (redirection, authentication, etc.) is better handled in the application.
The only cases .htaccess is useful in modern app development is for requests for static assets you don't want routed through the app (images, javascript, etc). Say you want to change MIME types of perhaps the content-disposition. But even in those cases, usually that should be documented as something to enable in the global server config, for two reasons:
1.) .htaccess needs to be checked each request for changes, slowing down your server
2.) you can't just assume .htaccess works, so the administrator needs to be aware of whats going on, in which case they may as well just put it in the global config. Unless your own a shared host like Dreamhost, in which case, yes, .htaccess is very useful.
There already exists an nginx module that talks to redis, it just does basic gets and doesn't support the entire redis protocol but it's a Start. Sorry don't have a link handy and I'm on my iPhone, a kittle google juice will find it for you.
Evan Miller's guide (already linked above) is great. But be prepared to dig into the Nginx code. Most things aren't documented, however, at least in my opinion, it has some of the cleanest large scale C code around. So, don't be scared to dig in.
by the way, I just realized this could be interpreted wrong- I don't mean to disparage crazy russian hackers. It just seems like a feasible explanation for the number and magnitude of cool or impressive things I've seen come out of russia.
The author Nginx, Igor Sysoev, mentioned lighttpd as the nearest competitor to Nginx. I don't really keep up with webservers, what is the story behind lighttpd stagnating vs Nginx growing in usage?
I don't know about anyone else but I used to use lighty and followed the path I think most people would: Learning Apache, as it's a default, then using something faster to serve static files and proxy to Apache for content (Lighty, briefly), then experimenting with proxying directly to code with things like scgi, etc.
I was at this point, playing with Lighty as an alternative, when nginx first starting poking its head about.
After trying one installation of it, it was so much quicker and smoother that I basically instantly ditched any ideas of bothering with much else. Then you start running sites with any real traffic, where it's more stable than anything I've ever seen, with no real effort and it makes the amount of bs that goes into lighty look ridiculous.
So I guess "the story" is it targets the same niche, and it's better. Bonus being that the deeper you go or the heavier into that niche you are, the wider the margin is.
lighttpd had a memory leak that was around unfixed for a very long time. Googling couldn't tell me whether it was now fixed or not, but there are many references to it (take a look!). It did strike me as a problem that an essential bug like that wasn't looked at quickly, even if it was a little difficult to pin down.
Perhaps this is a bit unfair, but this is what led me to move over to nginx from lighttpd.
I've been using lighttpd for static files for a few years and never had any problems. It's faster and less resource intensive than Apache, and it's literally never crashed.
How well does nginx work with Java stuff? I'm setting up a new server, and want to run Jira and Confluence from port 80 (issues.site.com, wiki.site.com) and Atlassian has an article for getting this to work on Apache, but not nginx.
Just switched from lighttpd a couple weeks ago. I've been convinced for a while now, but it's still nice to come here and see glowing reviews from Engine Yard and justin.tv.
I've been using nginx for a long time now, and it's been great. Currently, I host my rails app combining nginx and unicorn with bluepill to manage the processes. I just don't trust passenger. Another specialty is that I use UNIX sockets instead of tcp ports for the reverse proxy, something unique to nginx/unicorn I think.
The most compelling use case I've seen where Passenger loses to Unicorn is rolling restarts. The biggest trust issue that I've seen is that of source editability - Unicorn and Mongrel are easier to debug and patch, while Passenger requires a commanding knowledge of Apache to fix.
Really? I left lighttpd in disgust over it's nonsensical config files esp how they didn't work the way the docs claimed they did. After dicking with lighttpd to proxy the way I wanted for 1/2 a day I got nginx installed and configured in less than an hour.
Logical, but restrictive. I still prefer nginx as software, but lighty's config syntax doesn't tie you up in quite so many knots if you're trying to do things out of the ordinary.
This is my exact approach for dozens of tiny internal / "glue layer" HTTP servers, all over the place, for a long time now.
It's brilliant. Almost effort-free and insanely fast, in most cases.
It offers a really cool path too, in nginx + Py -> nginx + Py/C -> nginx + C plugin, to grow from a quick throw-together prototype to something that will take as much load as you can make up with silly benchmarking tools, while development takes a sensible route.
Edit: As a cool more concrete example, I used this trick to build a very quick 'hardware access layer' for an embedded device when it was insisted that Flash be used for the UI. It was 99% Python but with nginx to serve static files and proxy the rest to Flash, and CherryPy as an access layer to a local SQLite DB for data, with Python C calls to proprietary hardware drivers for the device.
Sounds sloppy perhaps but for what it had to do and how well it runs it was incredibly quick and painless to put together.
HAProxy supports sophisticated balancing schemes, rule-based backend selection, etc.
I.e., if Host header is X, and Ip is Y, but no cookie was provided, then use pool... with this balancing scheme.
nginx's proxy setup out of the box is useful, but I wouldn't consider it on par with things like ZXTM or a Big IP when it comes to robust balancing/fallback patterns and flexible routing rules.
If there's a module that provides all that, I'm happy to hear about it--I haven't found it yet.
Why haproxy? I've always seen it as more of an incoming traffic choice, and actually use it in front of nginx clusters in some cases, this seems confusing.
If you're doing SSL work, something that does SSL decryption needs to be in front.
So I can't do my fancy HAProxy routing rules on HTTP requests HAProxy can't read--it would be reduced to a simple TCP-level balancer then.
Basically, nginx is there for ssl, gzip, caching (redis/memcache mod), and all those http-plugin-goodness things. Simple proxy directly to HAProxy on loopback, which specializes in load balancing, traffic routing, failover, etc. Then, finally, the application code on N nodes behind HAProxy.
(By comparison, Apache is quite the memory hog and I still haven't figured out how to say the magic words to get it to not effectively crash my blog and every other site on the server if I burst to 10,000 visitors in an hour. That is not supposed to be a big number. Apache has 500 MB to play with and still can't keep up.)
I also find, and this might just be a matter of taste, that the configuration makes more sense to me than Apache configuration does. This is funny because Apache configuration is obsessively well-documented and Nginx configuration is not.
Additionally, some easy-to-use features cover weak points in typical Rails (&etc) deployment scenarios. The big one for me is file serving, since my website is essentially one big PDF printing press. The simplest level (works for me, won't work for Facebook) is just having the file anywhere accessible on the disk and having the application put a special header on the response saying "Hey, Nginx: give them this path.", then terminating Rails' involvement. That frees up your Mongrel to start doing hard work again and greatly, greatly, GREATLY decreases the resources you need to stream your 5 MB PDF, 20 MB executable, etc to the user.
So it scales down, but does it scale up? Ooooooooh yeah. Impressively so. See the tales of Wordpress deployment, where not a whole lot of Nginx gets hit with a year's worth of my traffic every couple of seconds and still keeps on trucking.