Static files with Nginx + Passenger
posted by gchatz 5 commentsNormally, when you setup Nginx and Passenger to serve your rails application, all static files are served by Nginx without hitting Passenger. What really happens is that all static files that do exist are served by Nginx and the rest are passed on to passenger.
For example
http://www.mydomain.com/javascripts/prototype.js
will be served by Nginx , but
http://www.mydomain.com/javascripts/iamastupidrobot.js
will continue to Passenger going all the way through the Rails stack. Instead of a simple 1ms nginx process , you get a full stack rails request with a route recognition error. Not good.
Missing or outdated images (specially if your site is big on content) or stupid robots searching for certain *.php (or *.js, or _vti_bin(?) or whatever) vulnerable files is common place. Why would you want those requests to pass on to passenger?
Using an asset host
One solution is to use an asset host for all static files by using an absolute url like
<script type="text/javascript" src="http://assets.mydomain.com/javascripts/prototype.js"></script>
instead of
<script type="text/javascript" src="/javascripts/prototype.js"></script>
Then you can make a separate entry for nginx for assets.mydomain.com with just a root directive to your public directory. This way static files will always be served by nginx, even the missing ones.
In addition you can specify multiple asset hosts and tell Rails to cycle through them. This is especially good for splitting the load among multiple servers and bypassing the 2 requests per ip browser constraint. What I don’t like with this approach is that simple image tags have to go through the image_tag helper, causing some overhead for no good reason.
Configure Nginx
set $asset F;
if ($request_filename ~* ".*\.(gif|jpg|css|jpeg|png|bmp|asp|php|_vti_bin|js)$") {
set $asset T;
}
if (!-f $request_filename) {
set $asset "${asset}T";
}
if ($asset = TT)
{
return 404;
break;
}
The first condition sets $asset to ‘T’ if the requested file is a static file (or a file that Rails doesn’t care about).
The second condition sets $asset to ‘TT’ if the requested file doesn’t exist.
The third condition breaks the rewrite flow and returns a 404.
There you go!

Comments (5)
Awesome site, but I can't subscribe in my news reader since your RSS feed is broken...
Found it a great launch
I thank you very much
Appreciation and respect
Heck on the theme of Creative Commons
Kois gone by and Hloowoowo ..
Awesome site, but I can't subscribe in my news reader since your RSS feed is broken...
Yeah Paypal is quite usefull. But i find it even more impressive that people are constantly working to improve this genius payment system. Thank your for this tutorial, its very useful.
Found it a great launch
I thank you very much
Appreciation and respect
Heck on the theme of Creative Commons
Kois gone by and Hloowoowo ..
Drop a comment: