by Scott Schecter

Serve Rack Based Ruby Applications

In this post I will demonstrate how to serve Rack based Ruby applications from the web server. This post assumes you have already deployed your application code. If you are looking for a quick an easy way to deploy your application check out my last post where I demonstrated how you can deploy applications via Git and SSH.

This will work for any Ruby framework that is Rack based such as Ruby on Rails or Sinatra. Most other popular Ruby web application frameworks are also based on Rack and should work as well.

There are many different ways to serve Rack based Ruby applications. You can use Nginx or Apache as your web server and reverse proxy. You can use Phusion Passenger, Unicorn, or Thin as your application server. Those represent just a few popular choices, there are also plenty of other web and application servers capable of serving Rack based Ruby applications available but not mentioned above. Each has it’s own strengths and weaknesses. Ultimately, the choice will need to be determined by you and your specific applications requirements.

Unless we have application requirement that dictates otherwise our default stack for serving Rack based Ruby applications currently at Schecter & Co. is using Phusion Passenger behind Nginx. This requires that Nginx be compiled with the Phusion Passenger module. If using FreeBSD as your web server operating system you will need to select this option when compiling the Nginx port. If you are using another operating system for your web server you will need to check with your operating system specific documentation to ensure Nginx is compiled with the Phusion Passenger module in your operating system’s package management system or compile Nginx with the Phusion Passenger module manually if necessary.

Below is a basic Nginx configuration file that demonstrates using Phusion Passenger as an application server behind Nginx as a web server and reverse proxy on FreeBSD.

For more information on the available Nginx configuration options please see here. For more information on the available Phusion Passenger configuration options please see here. To enable Nginx to load the Phusion Passenger module you will need to set four directives within the http section of your Nginx configuration. You set the passenger_root directive to the location of the Phusion Passenger root directory. You set the passenger_ruby directive to the location of your Ruby interpreter. You set the passenger_pool_idle_time to your desired value. Set this directive to 0 and application processes will not be shutdown unless it’s absolutely necessary. You set the passenger_max_pool_size to your desired value based upon the resources you have available on your web server. In the future, according to their website, Phusion Passenger may also be used for WSGI based Python applications as well as Node.js applications. At the time of this writing WSGI support is in beta and Node.js support is scheduled to be added next.

Nginx will serve as a web server and reverse proxy in this setup. Nginx will handle all requests and delegate Ruby application processing to Phusion Passenger module as needed. We will use Nginx to serve and cache all static files for maximum efficiency. This setup has proven to be a very capable and stable platform for delivering production Rack based Ruby web applications. Nginx itself is also very flexible and works with many different application servers. For example, you can also use php-fm behind Nginx to serve up PHP web applications as needed. This includes sites using popular PHP content management systems such as WordPress or Drupal.

You will notice that instead of embedding the configuration for each site in the main Nginx configuration file itself I include a separate folder which contains symbolic links to the actual per site configuration files. This keeps each sites configuration in it’s own file and makes administration of multiple sites much more manageable. For testing purposes you could include all configuration information within the main Nginx configuration file.

Next, let’s examine what one of thes site configuration files looks like for a Rack based Ruby application.

In the site configuration within the server section you will set the server_name directive to whatever hostnames your site is available under. You set the root directive to the public folder of your Rack based Ruby application so that Nginx will serve the static files. If you need to add any rewrites such as removing the www as seen above, you do so here within the server section of the sites configuration. You will also want to tell Nginx to cache the static files here by matching folder location names. Within the root location section of the server section of the site configuration set the passenger_enabled directive to on so Nginx knows to pass application processing to the Phusion Passenger module.

You should now be able to start Nginx and serve your Rack based Ruby applications by issuing the following command as a privileged user:

If you want to enable Nginx at startup issue the following command as a privileged user:

If you have any issues examine the Nginx error log for the cause. The location of this log file will depend upon your web server’s operating system. On FreeBSD it is found at /var/log/nginx-error.log. Please consult your operating systems documentation for it’s location on your system. We have now covered a basic Phusion Passenger enabled Nginx configuration which can be used to serve any Rack based Ruby application.

Leave a Comment

Your email address will not be published. Required fields are marked *