Running Rails on Nginx using Thin

I’m currently setting up my first Ruby on Rails environments. This post is mainly a reminder to myself of what steps I needed to take to get everything up and running. If it helps you, even better! Why not leave a comment and tell me?

If you find any errors or know of better ways to do things, please leave a comment!

Software used:

Ruby 1.9.2
Rubygems 1.8.10
Rails 3.1.1
RVM 1.8.6
Nginx 1.0.8
Thin 1.2.11
Gitolite
RSpec 2.6.4
Autotest

Create an RSA key and associate it with a server

To create an rsa key, run:

$ ssh-keygen -t rsa

The default name and location for the key will be:

~/.ssh/id_rsa
~/.ssh/id_rsa.pub

id_rsa is your private key and id_rsa.pub is your public key.

To associate a key with a server (so the rsa key is used instead of the server asking for your password), edit /etc/ssh/ssh_config and add:

Host <server>
IdentityFile ~/.ssh/id_rsa

To use this key with ssh, you need to tell the server to accept the key. Login to the server and run:

$ cd ~/
$ cat id_rsa.pub >> .ssh/authorized_keys

Install Git

To install git, you can use RVM’s very handy install script. Please note that by using this script, you put your computer in the hands of a script downloaded from the internet. Do not blame me if something goes terribly wrong. That said, the script is very useful, and you can read it in plain text by pointing your browser to the url in the command below. When you are comfortable running the script, execuse as follows:

$ sudo bash < <( curl -s https://rvm.beginrescueend.com/install/git )

Install Gitolite

Create a user called git – see Adding a non-root user in Linux.

Put your public rsa key in git’s home folder, e.g.:

/home/git/id_rsa.pub

Log in as user git and run:

$ git clone git://github.com/sitaramc/gitolite
$ gitolite/src/gl-system-install
$ gl-setup ~/id_rsa.pub

You should not have to change the settings, so just hit ctrl-x, write :q and hit enter to quit the editor.

Unless you have already associated your rsa key with the server, you have to do so now. See Create an RSA key and associate it with a server.

You must clone the gitolite-admin-repository to add repositories and users. Changes will take effect once you push the changes. Run:

$ cd /var
$ git clone git@<server>:gitolite-admin

Edit conf/gitolite.conf to add a new repository and push the changes:

$ cd /var/gitolite-admin
$ git commit -am "Added new repo"
$ git push origin master

You can now clone your new repository the same way you cloned gitolite-admin.

Read more here: http://sitaramc.github.com/gitolite/

Install Ruby Version Manager (RVM)

For comprehensive documentation, visit http://beginrescueend.com/

I like to use the RVM install script. Note that it must not be run directly as root. Instead, it must be run as a user with sudo abilities. The system should come with a non-root user by default, but some VPS-systems does not. For instructions on how to add a user to the system, see Adding a non-root user in Linux.

Before running the script, please read the warning under Install Git, as the same applies here.

As a sudo capable user, enter the following to install RVM for all users on the machine:

$ sudo bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
$ sudo apt-get update
$ sudo 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 

Now close your terminal window or log out of the ssh-session. Log back in and run:

$ type rvm | head -1

This should answer back that:

rvm is a function

If it does, the installation was a success.

Check if there are any dependencies you still need to fill by running:

$ rvm requirements

Now you should be good to go.

Note: When working with rvm, do not use sudo. If rvm needs sudo access, you must run rvmsudo, which will pass sudo access on to any commands that needs it.

Install Ruby

To install Ruby 1.9.2 run:

$ rvm install 1.9.2

RVM comes pre-equipped with RubyGems, so you do not have to install it separately. But you do want to create a “gemset” for this version of Ruby and the version of Rails that will be running on it:

rvm gemset create rails3.1.1

Then set RVM to use Ruby 1.9.2 and your new gemset per default:

$ rvm use 1.9.2@rails3.1.1 --default

Install Rails

This guide is pretty comprehensive: http://railsapps.github.com/installing-rails-3-1.html

To update all installed gems, run:

$ rvm 1.9.2 do gem 'update'

This should at least update the rake gem.

Now you can run:

$ gem install rails

and it should install the latest stable version of Rails, currently 3.1.1.

Make a home for your coming Rails’ apps:

$ sudo mkdir /var/rails

Check out a Gitolite repository to work on:

$ cd /var/rails
$ git clone git@<server>:my_new_app

Create a new Rails app:

$ rails new my_new_app

Install Nginx

This details installing nginx on Ubuntu. For other systems, please visit http://wiki.nginx.org/Install

Edit your /etc/apt/sources.list and add the following line:

deb http://nginx.org/packages/ubuntu/ lucid nginx

Then do:

$ sudo apt-get update
$ sudo apt-get install nginx

There is a lot to configuring nginx. Please check the following links:

http://wiki.nginx.org/Configuration
http://wiki.nginx.org/Pitfalls

Install Thin

Thin is the stuff that actually serves your Ruby. Nginx just delegates any requests for Ruby files to Thin.

To install Thin, run:

$ gem install thin

Thin also needs a Javascript environment installed on the server in order to run. Add the following to your gemfile:

gem 'execjs'
gem 'therubyracer'

and then run

$ bundle install

Make Thin start at boot:

When using RVM, Thin must be started through RVM, and therefore the usual method needs some additions. Start with:

$ thin install
$ sudo /usr/sbin/update-rc.d -f thin defaults
$ thin config -C /etc/thin/<appname>.yml -c /var/rails/<appdir> --servers 3 -p <portnumber>

Generate an RVM wrapper:

$ rvm wrapper 1.9.2@rails3.1.1 bootup thin

You might have to edit the DAEMON variable in /etc/init.d/thin. It should say something like this:

DAEMON=/usr/local/rvm/wrappers/ruby-1.9.2-p290@rails3.1.1/thin

To start Thin, reboot or run:

$ sudo service thin start

To restart Thin without rebooting the server, enter:

$ sudo service thin restart

Credit to Ola Tuvesson for his answer on Stack Overflow.

If you get a “502 Bad Gateway” from Nginx when trying to reach the site, Nginx can not talk to Thin. Make sure Thin is running on the right ports and double check your Nginx config.

Installing and running Autotest:

$ gem install autotest
$ gem install autotest-ruby-pure

To run, just cd to Rails root and run:

$ autotest

If RSpec is installed, Autotest should detect this automatically.

Tutorial at http://ph7spot.com/musings/getting-started-with-autotest

Deploying to Heroku:

To deploy to Heroku, the gem “pg” must be added to the Gemfile:

group :production do
# gems specifically for Heroku go here
gem "pg"
end
# Skip attempting to install the pg gem
$ bundle install --without production

Credit to Justice for his answer on Stack Overflow.

Using jQuery with Rails 3.1.1

Adding <%= javascript_include_tag “application” %> to a Rails 3.1.1 app might produce the following errors:

couldn't find file 'jquery'
couldn't find file 'jquery_ujs'

The easiest solution seems to be to download jQuery and jQuery ujs and save them in /app/assets/javascript/ as “jquery.js” and jquery_ujs.js” respectively.

Adding a non-root user in Linux

If you don’t have a non-root user, you are obviously working as root already, so no sudo required.

Substitute “new_user” with your desired new username.

$ adduser new_user

Enter password when asked. To add the new user to the list of sudoers run visudo as root (can only be run as root, not using sudo):

$ visudo

visudo should start in command mode. Press i to enter insert mode. Find the line:

root ALL=(ALL) ALL

and enter a new line for the new user below it, so that it looks like this:

root ALL=(ALL) ALL
new_user ALL=(ALL) ALL

Press esc to enter command mode. Enter :wq to write the changes to disk and quit.

3 thoughts on “Running Rails on Nginx using Thin

  1. Hi Adrian,

    I was wondering how you deployed nginx with rails on heroku? Do they have to be separate apps? Can you show or email me the process like where you put your conf files and all, and how you set up nginx to run on heroku?

    Regards,
    Sagar

    • Hi Sagar,

      I don’t know which web server Heroku uses, but as far as I know, you can’t run your own web server with them. The question that the article above addresses is “I have a Linux environment; how do I run an effective Ruby on Rails server on it.”

      One of the main advantages of using a service such as Heroku to host your Ruby on Rails code, is that you don’t have to worry about a whole lot of what this article details. With Heroku, you just need to get an account, choose how much “power” you need (and are willing to pay for), and push your code using git. Heroku will do the rest for you.

      Thank you very much for the question!
      Regards,
      Adrian

  2. Adrian,

    Thank you for the reply. I had successfully set up nginx with rails application in my local box (windows). I just did not have any idea how to set it up at heroku with rails. I saw your post and I was wondering if you have any idea about that.

    I am sticking to heroku as long as I can get some free stuff. Once my application seems to start grow bigger, I will have them deployed in a dedicated server. And, this article might be a help at that time like you said. Thanks again.

    Regards,
    Sagar

Leave a Reply

Your email address will not be published. Required fields are marked *