Selecting a web server and an application server
Redmine as a Ruby on Rails web application should be run under a web server. This can be an independent web server (such as Apache, Nginx, or Lighttpd) that runs Ruby on Rails using either Passenger or FastCGI, or a dedicated Ruby web server such as Puma, Unicorn, Rainbows!, or Thin.
A big option list, isn't it? And these are not even all the possible options. Redmine can also be used with JRuby under a Java virtual machine. It can be run under standalone Passenger, under Mongrel, WEBrick, and more. But the previously mentioned options were chosen by practical use, and therefore they are the most common. That's why we are reviewing only those options here.
These options can be divided into three categories:
- A dedicated Ruby web server
- A dedicated Ruby web server and, for example, Nginx as a load balancer
- A separate web server with a Ruby module
Ruby is often compared to PHP, but actually these technologies are very different. For PHP guys, which include me as well, the use of a web server written in Ruby to run a Ruby application sounds weird. But in fact, a Ruby application, like a Java one, runs under a virtual machine. Therefore, Apache, for example, needs to run a Ruby virtual machine in order to run a Ruby application. This way, eventually we get at least three processes: a web server, an application server, and the application itself. So, running a Ruby application under a Ruby server seems to be reasonable, because in this case, we get only two processes: an application server which serves as a web server as well and the application.
The lack of good multithreading support is a known problem of Ruby virtual machines, and this is the main reason people use a Ruby application server in conjunction with a web server to run Ruby applications in production. Thus, they launch many instances of a Ruby server and use some web servers as a load balancer to forward requests to these instances and as a web server to dispatch the static content (images, CSS files, and so on). The best combination for this category, according to many benchmark results, is Nginx plus Puma or Unicorn.
But in practice, for this configuration, people also often use a dedicated load balancer in addition to the web server. This can be either a special application, such as HAProxy, or a web server with support for reverse proxy mode. For Apache, such a mode is provided by the mod_proxy
module. Nginx and Lighttpd have built-in proxies. In addition, some people use special software for monitoring of Puma/Unicorn instances, for example, Monit.
Certainly, the category just discussed is for advanced use and high-loaded services. The most commonly used, easiest to install, and best documented is the third category: a web server running a Ruby application using the Passenger module (also known as mod_rails
) or the FastCGI
module. The Passenger module is, in fact, another Ruby application server. It differs from Puma/Unicorn in that it runs as a module of a web server and not as a standalone application server (while the latter is possible). Unfortunately, the Passenger module has some limitations. It does not work under Windows and is not available for Lighttpd. For Lighttpd to run Ruby applications, people have to use FastCGI. Here, FastCGI is the name of the protocol that is used by web servers to communicate with Ruby virtual machines. Modules of the same name that implement this protocol exist for Lighttpd, Apache, and Nginx.
Generally, Passenger is more popular than FastCGI. Thus, it is used by the BitNami Redmine stack and TurnKey Redmine appliances (systems for easy Redmine deployment). It is suitable not only for small-sized and middle-sized websites, but also works great for high-loaded ones. Therefore, guys from the Ruby on Rails framework recommend using Passenger in favor of other options (check out http://rubyonrails.org/deploy).
When run under a web server, Passenger creates at least two processes: itself and an application instance. This can become a problem if it is used on a cheap OpenVZ-powered VPS hosting, where the amount of memory that is used by an application is very critical. This is where FastCGI helps. When run using FastCGI, Redmine occupies at least one process (an application instance).
If you still don't feel sure about which option to choose, let's summarize:
- If you plan to use Redmine for a heavy-loaded website, you should consider using Nginx with Puma/Unicorn and possibly HAProxy
- For all other cases, or if you are just unsure, go with Apache or Nginx and the Passenger module
While choosing, you should also consider your other requirements and services you plan to run on the same server. For example, you will definitely need Apache if you plan to use Redmine.pm
for authentication of Subversion/Git users against Redmine, as it's an Apache module.