Installing Ruby on Rails, Mongrel and use with Nginx and Apache

In this article I describe how to go about installing Ruby on Rails and Mongrel for use with Nginx or Apache on a linux machine. In my case the machine had Ubuntu Feisty installed but these instructions should be equally applicable on other linux distributions, like Red Hat, Fedora or Suse.

Please give feedback in the comments in case something didn’t work for you and how you solved it so that next person won’t have to go through the same problems. Improvements are also welcome.

First install Ruby

We’ll do it by compiling from source, like real men and women do. This gives us complete control of which version of Ruby that is used.

On Ubuntu make sure you have the build-essential, zlib1g-dev, openssl and libssl-dev packages installed. If you are using another distribution make sure similar things are installed.

  1. $ mkdir src
  2. $ cd src
  3. $ mkdir ruby-1.8.6
  4. $ wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.6.tar.gz
  5. $ tar xzf ruby-1.8.6.tar.gz
  6. $ cd ruby-1.8.6
  7. $ ./configure

If you get a checking size of int… configure: error: cannot compute sizeof (int) error first try to install the build-essential package. If that doesn’t help, you, like me, might have a busted libc6-dev installation. Reinstall that package ($ sudo apt-get –reinstall install libc6-dev). That fixed the problem for me.

The checkinstall package is a smart thing. If you build something from source it will create a distribution package for you so that you easily can remove the package later on. Install the package with apt-get install checkinstall. On a Debian or Ubuntu system checkinstall will create a dpkg package but if used on a Red Hat, Fedora or Suse system you will get a rpm package.

Now we can continue with installing ruby.

  1. $ make
  2. /etc/checkinstallrc and change INSTALL=1 to INSTALL=0 at the bottom of the file.
  3. $ sudo checkinstall
  4. $ sudo dpkg -i ruby_1.8.6-1_i386.deb

Then we install Rubygems

  1. $ cd ../..
  2. $ mkdir rubygems-0.9.4
  3. $ cd rubygems-0.9.4
  4. $ wget http://rubyforge.org/frs/download.php/20989/rubygems-0.9.4.tgz
  5. $ tar xzf rubygems-0.9.4.tgz
  6. $ cd rubygems-0.9.4
  7. $ sudo ruby setup.rb

If you get no such file to load — zlib (LoadError) you don’t have the zlib1g-dev package installed, which gave you a ruby without zlib support when you compiled it. Install the package and start over from the beginning.

And Ruby on Rails

  1. $ sudo gem install rails --include-dependencies

If you get the following error:

ERROR: While executing gem … (Gem::GemNotFoundException)
Could not find rails (> 0) in any repository

Just run the command again.

Now it’s time to install Mongrel

  1. $ sudo gem install mongrel
  2. $ sudo gem install mongrel_cluster
  3. $ sudo cp /usr/local/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.2/resources/mongrel_cluster /etc/init.d/

Test your Mongrel install by running Mongrel in the root of a Rails application. If it works you should be able to access your application at http://localhost:3000.

  1. $ cd rails_app
  2. $ mongrel_rails start -d
  3. Go to http://localhost:3000 with a browser (e.g. lynx)
  4. $ mongrel_rails stop

Now we need to do the cluster specific setup, do that by following these Using Mongrel Cluster instructions.

Capistrano installation

  1. $ sudo gem install capistrano
  2. $ cd rails_app
  3. $ capify .
  4. Edit the config/deploy.rb script and set the :application, :repository, :deploy_to, :user, :app, :web, :db variables
  5. $ cap deploy:setup
  6. $ cap -q deploy:check

If you don’t get You appear to have all necessary dependencies installed fix the errors you get and execute the command again.

If you get connection failed for: hostname (LoadError: no such file to load — openssl) you need to install the openssl and libssl-dev packages and then recompile ruby.

  1. Until Mongrel starts to include recipes for Capistrano 2.0 use the stuff from Mongrel and Capistrano 2.0
  2. In config/deploy.rb add the following:
    set :group_writable, false
    set :keep_releases, 2
    set :mongrel_conf, "#{deploy_to}/current/config/mongrel_cluster.yml"
    
  3. And at the end of the file add the following:
    after "deploy:symlink", :fix_session_permissions
    
    task :fix_session_permissions, :roles => :web do
      run "chmod 777 #{current_path}/tmp/sessions"
    end
    

Alright, let’s do the first deploy.

$ cap deploy

Naturally it won’t work. You might remember that we configured the mongrel servers to run as the mongrel user. For the servers to be able to write log files the shared/log directory has to be either world writable (not really wanted) or owned by the mongrel user (the preferred choice). So fix that on the deploy machine. At the same time do the same for the shared/pids directory.

Now create the needed database user, create the database and make sure the database.yml configuration file is correct. Then do another deploy and pray that it works!

Make the Mongrels start automatically at boot time

If you followed the Using Mongrel Cluster instructions you were told to copy a file to /etc/init.d/mongrel_cluster and then link to your mongrel_cluster.yml in the /etc/mongrel_cluster directory. That should be all the magic that is needed.

After you verified that it works run sudo update-rc.d mongrel_cluster defaults so it will be added to the services that are automatically started when the machine boots.

Nginx configuration

On this wiki page you can find a working site configuration. This is my /etc/nginx/sites-available/host file.

upstream host_mongrel {
        server 127.0.0.1:9100;
        server 127.0.0.1:9101;
}

server { listen 80; server_name host.se www.host.se; access_log /var/log/nginx/host.se.access.log;

    root   /u/host.se/www/current/public;
    index  index.html index.htm;

    location / {
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect false;

            if (-f $request_filename/index.html) {
                    rewrite (.*) $1/index.html break;
            }
            if (-f $request_filename.html) {
                    rewrite (.*) $1.html break;
            }
            if (!-f $request_filename) {
                    proxy_pass http://host_mongrel;
                    break;
            }
    }

    error_page   500 502 503 504  /50x.html;

    location = /50x.html {
            root   html;
    }

Configure Apache

<

p>I haven’t done this myself but it should be fairly easy to follow the instructions in the Configuring Apache 2.2, Mongrel and mongrel_cluster section in this Deploying Rails on Ubuntu Dapper article.

<

p>You might need to do the following to the get the needed apache2 modules enabled.

  1. $ sudo /usr/sbin/a2enmod proxy_balancer
  2. $ sudo /usr/sbin/a2enmod headers

Sources