Running Rails applications: Choosing a server
Once you develop a web application in Rails, and works great in the embedded web server rails comes with, or mongrel, you may ask yourself how to run the application for production.
It may seem it's easy to decide, and in fact, all the solutions will be around Apache2 or lighttpd + FastCGI.
Actually, as you may have noticed, the performance difference between Apache2 and lighttpd is not the problem. They both work fine (and if you don't need something specific only available for one of the web servers, you can choose the one you prefer). The biggest problem is the FastCGI module.
The FastCGI module for Apache (libapache2-mod-fastcgi in Debian systems) does not perform good, even changing the default configuration (/etc/apache2/mods-available/fastcgi.conf)
By default, the module runs in dynamic mode, which is, you give a minimum and maximum of FastCGI processes running, and these are started or killed automatically when it's needed.
<IfModule mod_fastcgi.c>
AddHandler fastcgi-script .fcgi
...
FastCgiConfig -minProcesses 2 -maxProcesses 6
...
</IfModule>
It can also be configured in static mode, where the number of FastCGI processes specified are started when Apache starts, and remain running. You can adjust the idle timeout parameter to the needs of your application. In the example, it gives a 60 second limit to process the query.
<IfModule mod_fastcgi.c>
AddHandler fastcgi-script .fcgi
...
FastCgiServer -idle-timeout 60 -processes 4
...
</IfModule>
I experienced better performance using FastCGI in static mode for Rails, but it is not good enough. The dispatch.fcgi processes freeze from time to time and the application is either slow or crashes.
The solution I am currently using is Apache2 + libapache2-mod-fcgid. mod-fcgid is a module for Apache2, compatible with FastCGI that I found to perform much better than the other solutions above. Even with the default configuration is much better than the FastCGI module for Rails.
There are some small things you have to change to use fcgid, though. First of all, you will have to change the handler in the .htaccess file in the public/ directory of your Rails application.
You will have to search for the line:
AddHandler fastcgi-script .fcgi
replacing it with:
AddHandler fcgid-script .fcgi
If you use HTTP Authentication, you will notice that the header is not passed through the cgi to the rails application. You will have to use RewriteRules to pass it. Again, in .htaccess, search for the line:
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
and replace it with:
RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
Now you can access the Authorization header the usual way:
if request.env.has_key? 'REDIRECT_X_HTTP_AUTHORIZATION'
authdata = request.env['REDIRECT_X_HTTP_AUTHORIZATION'].to_s.split
end
It may seem it's easy to decide, and in fact, all the solutions will be around Apache2 or lighttpd + FastCGI.
Actually, as you may have noticed, the performance difference between Apache2 and lighttpd is not the problem. They both work fine (and if you don't need something specific only available for one of the web servers, you can choose the one you prefer). The biggest problem is the FastCGI module.
The FastCGI module for Apache (libapache2-mod-fastcgi in Debian systems) does not perform good, even changing the default configuration (/etc/apache2/mods-available/fastcgi.conf)
By default, the module runs in dynamic mode, which is, you give a minimum and maximum of FastCGI processes running, and these are started or killed automatically when it's needed.
<IfModule mod_fastcgi.c>
AddHandler fastcgi-script .fcgi
...
FastCgiConfig -minProcesses 2 -maxProcesses 6
...
</IfModule>
It can also be configured in static mode, where the number of FastCGI processes specified are started when Apache starts, and remain running. You can adjust the idle timeout parameter to the needs of your application. In the example, it gives a 60 second limit to process the query.
<IfModule mod_fastcgi.c>
AddHandler fastcgi-script .fcgi
...
FastCgiServer -idle-timeout 60 -processes 4
...
</IfModule>
I experienced better performance using FastCGI in static mode for Rails, but it is not good enough. The dispatch.fcgi processes freeze from time to time and the application is either slow or crashes.
The solution I am currently using is Apache2 + libapache2-mod-fcgid. mod-fcgid is a module for Apache2, compatible with FastCGI that I found to perform much better than the other solutions above. Even with the default configuration is much better than the FastCGI module for Rails.
There are some small things you have to change to use fcgid, though. First of all, you will have to change the handler in the .htaccess file in the public/ directory of your Rails application.
You will have to search for the line:
AddHandler fastcgi-script .fcgi
replacing it with:
AddHandler fcgid-script .fcgi
If you use HTTP Authentication, you will notice that the header is not passed through the cgi to the rails application. You will have to use RewriteRules to pass it. Again, in .htaccess, search for the line:
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
and replace it with:
RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
Now you can access the Authorization header the usual way:
if request.env.has_key? 'REDIRECT_X_HTTP_AUTHORIZATION'
authdata = request.env['REDIRECT_X_HTTP_AUTHORIZATION'].to_s.split
end



























