Nginx as Reverse Proxy and Cache for Thin/Sinatra
Phrogz.net runs a variety of different web applications, such as the page you’re reading now and ObjJob. Most of the web applications are written in Ruby, using the Sinatra as the web framework and Thin as the server. All of these apps, however, sit behind a single Nginx process that acts as the web server for all of Phrogz.net.

As shown above, a single nginx.conf file controls multiple websites. You use a server{ … } block for each logical server, providing the host name used to match the rules therein.
Most of the magic takes place in the try_files command:
- The text in blue—
$uri—says, “If you can find a file in therootdirectory matching the request, just send that first.”- Requests for
http://phrogz.net/favicon.pngandhttp://phrogz.net/images/foo.gifwill have Nginx serve the file straight from the hard drive.
- Requests for
- The text in green—
/cache$uri/index.html /cache$uri.html—says, “Next, look in thecachefolder and see if you can find a file matching the request, but ending in.html. Oh, and if the request ends in a slash, look for a file namedindex.htmlinside that folder.”- A request for
http://phrogz.net/foowould serve up/var/www/phrogz.net/public/cache/foo.htmlif that file exists. - A request for
http://phrogz.net/foo/bar/would serve up/var/www/phrogz.net/public/cache/foo/bar/index.htmlif that path and file exists.
- A request for
- Finally, the text in beige—
@proxy—says, “If you couldn’t find any files, then just serve up the @proxy.” Which passes off control to thesinatra.phrogzupstream. Which, as shown, uses a round-robin between two different web servers (Thin processes) running on different ports.
A future article will cover using sinatra/cache to automatically populate the cache directory based on controller requests. With just this, however, you have the ability to crawl your website and save out static copies and have them served up in place of the dynamic ones. For example, the ObjJob list of Properties takes almost 10 seconds for Haml to create the 450k of code, but it is served immediately from a disk-based static copy on the server.