Capistrano and Passenger Part 2

As Karl Varga pointed out in his comment on my previous post on Capistrano and Passenger (here) my apache rewrite rules did not send back the proper HTTP status codes. Now with the improved and tested rules the 503 status code is returned.

1
2
3
4
5
6
7
8
9
ErrorDocument 503 /system/maintenance.html

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
# RewriteCond %{REQUEST_URI} !^/images/
# RewriteCond %{REQUEST_URI} !^/robots.txt
# RewriteCond %{REQUEST_URI} !^/sitemap
RewriteRule ^.*$ [redirect=503,last]

If your maintenance page has images on it than you can enable line 6 by removing the ‘#’.

See also Chris K’s article.

Namespace Route and Form_for Method

When you have a namespace in your routes.rb like this:

1
2
3
  map.namespace :admin do |admin|
    admin.resources :users
  end

And you like to have a form like this:

1
2
<% form_for(@user) do |f| %>
  <%= f.error_messages %>

Change the form_for in this and you’re good to go!

1
2
<% form_for([:admin, @user]) do |f| %>
  <%= f.error_messages %>

This might save you some time. ;-)

Gem 1.2.0 Released

Yesterday gem 1.2.0 was released. This is a release we’ve all been waiting for! This version doesn’t have the ‘bulkupdate’ and doesn’t consume that much memory as before. So update your gem for the last time with the -B parameter. Like this:

1
gem update --system -B 1000000

Before version 1.2.0 I had to do on my VPS:

1
gem install -B 1000000 --no-rdoc --no-ri rails

But now I can do:

1
gem install --no-rdoc --no-ri rails

And it’s finished in a sec!

Capistrano and Passenger

To use Capistrano on a Passenger enabled host, you need to add the following lines to your config/deploy.rb file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace :deploy do
  desc "Restarting mod_rails with restart.txt"
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "touch #{current_path}/tmp/restart.txt"
  end

  desc "Stop task is a deploy.web.disable with mod_rails"
  task :stop, :roles => :app do
    deploy.web.disable
  end

  desc "Start task is a deploy.web.enable with mod_rails"
  task :start, :roles => :app do
    deploy.web.enable
  end
end

Because in passenger there is no way of stopping or starting your Rails application, I’ve changed the deploy:start and deploy:stop to deploy:web:enable and deploy:web:disable. The deploy:restart is used by the deploy task, so now your deployment works as expected.

Update: Don’t forget to add the rewrite rules to your apache virtual host config, otherwise the enable disable tasks won’t work.

1
2
3
4
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]

Plesk, Passenger (Mod_rails), Ruby Enterprise Edition & Ruby on Rails

Currently I have a Plesk 8.4 installation running on a CentOS 5 VPS. First I had my Ruby on Rails websites running on multiple mongrel servers (cluster) but it took too much RAM of my VPS and it was very complicated to add more websites. So now I’ve installed Passenger (make sure you check the screencast on the Passenger website!) which makes adding websites very easy. Also I’ve installed RubyEnterpriseEdition which reduces the memory needed for Ruby applications, including Ruby on Rails. Below I’ll describe the steps I took to complete this installation.

Passenger

Just follow the steps described on the Passenger website. Run as root:

1
gem install passenger

The following command verifies if all the dependencies are installed, if not it suggests what rpm’s should be installed and exits. If all the dependencies are met, it compiles the Apache 2 module and installs the module.

1
passenger-install-apache2-module

Personally I hate installers who do a lot of stuff you can’t control, but this one does only the stuff it should do and will not break your current setup. After the module is installed you need to add the module to Apache. So I created the file /etc/httpd/conf.d/passenger.conf with the following contents:

1
2
3
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.1/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.1
PassengerRuby /usr/bin/ruby

Restart Apache.

1
/etc/init.d/httpd restart

At this point you have installed Passenger and the only thing to make a Ruby on Rails application work, is to point the Apache DocumentRoot directive to the public directory of your Rails application.

RubyEnterpriseEdition

Download RubyEnterpriseEdition (REE), extract the file and run the installer. As described on the REE website.

1
2
3
wget http://rubyforge.org/frs/download.php/38777/ruby-enterprise-1.8.6-20080624.tar.gz
tar xzvf ruby-enterprise-1.8.6-20080624.tar.gz
./ruby-enterprise-1.8.6-20080624/install

This installer will install it’s own Ruby environment to /opt. This is good, because it will not touch your current Ruby environment. After the installation you’ll have a separate gem installed which is version 1.2.0. The version without the gem bulkupdate, which causes a lot of memory problems on VPS’es. The following commands I’ve used to install different gems. Mysql did not install easily, but with the -- --with-mysql it worked. Note the --no-rdoc and --no-ri because we’re on a production environment we don’t need the documentation.

1
2
3
4
/opt/ruby-enterprise-1.8.6-20080624/bin/gem install --no-rdoc --no-ri rails
/opt/ruby-enterprise-1.8.6-20080624/bin/gem install --no-rdoc --no-ri -v 1.2.6 rails
/opt/ruby-enterprise-1.8.6-20080624/bin/gem install --no-rdoc --no-ri -v 2.0.2 rails
/opt/ruby-enterprise-1.8.6-20080624/bin/gem install --no-rdoc --no-ri mysql -- --with-mysql-config

If you have all the gems installed which you need in your Rails applications, it’s time to switch the Ruby Interpreter to the REE installation, we do this by replacing the PassengerRuby line in the /etc/httpd/conf.d/passenger.conf file.

1
PassengerRuby /opt/ruby-enterprise-1.8.6-20080624/bin/ruby

Fine-tuning

Depending on the available RAM on your VPS, you should add the following line to passenger.conf:

1
PassengerMaxPoolSize 2

To prevent Passenger from invoking to many instances of the Rails app.

Plesk

The only thing you have to do in Plesk is to modify the DocumentRoot. I’ve made a app directory where I deploy my Rails application with Capistrano. Create the file vhost.conf in the config directory of your domain.

1
DocumentRoot /var/www/vhosts/DOMAIN.COM/app/current/public

After that run the following command to let Plesk reconfigure your domain and add a include for your vhost.conf file.

1
/usr/local/psa/admin/sbin/websrvmng -u --vhost-name=DOMAIN.COM

Copyright © 2013 - Tom Pesman - Powered by Octopress