Set up Rails 3.2.2 with Passenger, rvm and ngnix

Ruby on Rails is becoming more feature rich and powerful by every release. Naturally the steps to get it working in production environment are also being changed. I've been trying to set up Rails 3.2.2 for a while and here's the method that finally worked. This method should work for the new Rails release, 3.2.3 too.

Install Server Operating System

We have a large pool of operating systems to select for our server. Though Debian Squeeze and CentOS have proved their stability in serving rails applications, I would prefer a LTS version of Ubuntu Server edition. I did a small survey, Many experienced programmers said they are using Ubuntu server as it's easy to maintain, Packages are in plenty and has better stability. Also Canonical promises to give us 5 years of support for LTS edition operating systems. Current LTS edition is Ubuntu Server 10.04

Install RVM

Ruby Version Manager(RVM) helps to manage multiple ruby versions in a single machine. RVM helps us to quickly switch Ruby/Rails versions. Before installing RVM, we need to install git, curl and autoconf. Use the following command to do it:

[code]$ sudo apt-get -y install git-core curl autoconf[/code]

Then install and configure RVM,

[code]

$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile

[/code]

Source ~/.bash_profile to add rvm as a function to shell

[code]$ source ~/.bash_profile[/code]

Install Ruby

Before installing Ruby, we need to install all dependency packages. The following command lists the dependency packages.

[code]$ rvm requirements [/code]

We can see a line with lots of package names, something like the following. Execute it directly with sudo in shell to install packages:

[code]

sudo /usr/bin/apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion [/code]

Next step is to install Ruby. Current latest version of Ruby 1.9.3. Let's install it

[code]$ rvm install 1.9.3[/code]

It will take a few minutes to fetch source, configure and compile.

After completing installation, we can set 1.9.3 as the default version:

[code]$ rvm use 1.9.3 --default[/code]

Install passenger

Passenger is a free module for Apache and nginx to run Ruby applications. Luckily it's available as a Ruby gem and it's easy to install and configure it.

Install passenger gem

[code]$ gem install passenger[/code]

Install and configure nginx

[code]$ rvmsudo passenger-install-nginx-module[/code]

This command downloads nginx source code, builds it and finally configures passenger for us. Default location of ngnix is /opt/nginx and we can find the configuration in /opt/nginx/conf/nginx.conf

If you open nginx configuration, you can see the following lines have been already added into it in 'http' configuration:

[code]

passenger_root /home/ershad/.rvm/gems/ruby-1.9.3-p125/gems/passenger-3.0.11;
passenger_ruby /home/ershad/.rvm/wrappers/ruby-1.9.3-p125/ruby;

[/code]

Install Rails

Before installing rails, we will create a gemset. Gemset is feature of RVM where we can create multiple gemset to store different gems of different versions.

Let's create a gemset for Rails 3.2.2

[code]

$ rvm gemset create rails322

$ rvm gemset use rails322

[/code]

Installing rails is pretty straight forward.

[code]$ gem install rails -v 3.2.2[/code]

If you are not interested in the documentation that comes along with rails gem, use the following command instead

[code]$ gem install rails -v 3.2.2  --no-ri --no-rdoc [/code]

Install nginx init script

nginx init script by Jason Giedymin helps us to administer web server easily.

[code]
$ cd
$ git clone git://github.com/jnstq/rails-nginx-passenger-ubuntu.git
$ sudo mv rails-nginx-passenger-ubuntu/nginx/nginx /etc/init.d/nginx
$ sudo chown root:root /etc/init.d/nginx
[/code]

Deploying application
Let's store all rails applications under /var/rails_apps/ directory. Let's make such a folder
[code]
$ sudo mkdir -p /var/rails_apps
$ sudo chmod 777 /var/rails_apps/ #giving full file permissions
[/code]
Let's create a sample rails application in rails_apps directory
[code]
$ cd /var/rails_apps
$ rails new helloworld
$ cd helloworld
$ vim Gemfile # and uncomment the line to include 'therubyracer' gem. We need a javascript runtime
$ bundle install
$ bundle exec rake assets:precompile #Precompile assets to public/ dir

[/code]
Next step is point ngnix to this location. Add the following snippet in /opt/nginx/conf/nginx.conf
[code]

server {
listen 80;
server_name example.com;
rails_env production;
root /var/rails_apps/helloworld/public; # <--- be sure to point to 'public'!
passenger_enabled on;
}

[/code]

Restart the server

[code] sudo /etc/init.d/nginx restart[/code]

Your application must be alive and running now! :)

Points to remember

1) Rails application doesn't get updated when we change the code. This is because we need to restart passenger explicitly

Restarting passenger is easy, we just have to create a file 'restart.txt' in tmp/ dir of the application. For example

[code]

$ cd /var/rails_apps/helloworld

$ touch tmp/restart.txt

[/code]

2) Always precompile assets after generating controller or scaffold

3) Make sure you are migrating in 'production' environment. This can be done using the following command.

[code] rake db:migrate RAILS_ENV=production[/code]

4) When you get errors related to routes, check the list of all routes

[code] $ rake routes [/code]

5) When something goes wrong, see log/production.log

6) If you happen to get passenger errors related to missing gems, just add those gems in Gemfile and use the following command

[code] $ bundle install --path vendor/bundle [/code]

That's it. Happy hacking with Ruby on Rails. Thank you.


Leave a Comment