Install Ruby on Rails on Ubuntu Server

Getting Ruby on Rails running on an actual production Linux server is actually not-trivial. It takes quite a bit of sysadmin knowledge to do this.

One line installer

I’ve combined the entire installation process into a one line installer. I’ve tested this with Amazon EC2 Ubuntu 12.04 instances and we use this at Ballistiq to get a server up really fast.

So copy and paste this into your command line and it should have Ruby, Nginx, Passenger all ready to deploy your Rails apps in about 15 minutes. 🙂

sudo apt-get install -y git && git clone git://github.com/ballistiq/ruby-passenger-nginx-installer.git && bash ./ruby-passenger-nginx-installer/install.sh

Get all dependencies

Get all your base dependencies by running:

$ sudo apt-get update
$ sudo apt-get -y install build-essential zlib1g-dev libssl-dev libreadline-dev libyaml-dev libcurl4-openssl-dev curl git-core python-software-properties libsqlite3-dev

If you are going to be using MySQL, you’ll need the MySQL headers:

$ sudo apt-get -y install libmysql++-dev 

Install Ruby from Source

Now you have to install Ruby. You could do this using RVM but for the purpose of this tutorial I’ll show you how to just compile from source and have a system-wide Ruby 1.9.3 running.

Basically download the latest source from the official Ruby website. Unpack it, run ./configure, make then sudo make install. We configure our rubygems to skip installation of documentation to speed things up.

$ mkdir ~/src
$ cd ~/src
$ wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p286.tar.gz
$ tar -zxf ruby-1.9.3-p286.tar.gz
$ cd ruby-1.9.3-p286
$ ./configure
$ make
$ sudo make install
$ echo "gem: --no-ri --no-rdoc" >> ~/.gemrc
$ sudo gem install bundler

Installing Phusion Passenger and Nginx

For our web server we will use the extremely fast Nginx reverse proxy server along with Phusion Passenger. Instead of installing Nginx using the apt-get package manager, we’ll need to install it from source for it to run with Passenger. Thankfully, Passenger does this for us.

$ sudo gem install passenger
$ sudo passenger-install-nginx-module --auto --prefix=/opt/nginx --auto-download

This will install Nginx at /opt/nginx, and Phusion Passenger.

Nginx service control

Create a new file /etc/init.d/nginx and copy/paste this in:

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/opt/nginx/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
DAEMON=/opt/nginx/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
        . /etc/default/nginx
fi

set -e

case "$1" in
  start)
        echo -n "Starting $DESC: "
        start-stop-daemon --start --quiet --pidfile /opt/nginx/logs/$NAME.pid \
                --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --quiet --pidfile /opt/nginx/logs/$NAME.pid \
                --exec $DAEMON
        echo "$NAME."
        ;;
  restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --quiet --pidfile \
                /opt/nginx/logs/$NAME.pid --exec $DAEMON
        sleep 1
        start-stop-daemon --start --quiet --pidfile \
                /opt/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  reload)
          echo -n "Reloading $DESC configuration: "
          start-stop-daemon --stop --signal HUP --quiet --pidfile     /opt/nginx/logs/$NAME.pid \
              --exec $DAEMON
          echo "$NAME."
          ;;
      *)
            N=/etc/init.d/$NAME
            echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
            exit 1
            ;;
    esac

    exit 0

Now you can start/stop/restart Nginx really easily by tying:

$ sudo service nginx start
$ sudo service nginx stop
$ sudo service nginx restart

Log Rotation

Don’t forget that because we installed Nginx from source, its log files are not automatically being rotated by Ubuntu. We have to configure this!

Create a new file /etc/logrotate.d/nginx

Copy and paste this into the file:

/opt/nginx/logs/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                [ ! -f /opt/nginx/logs/nginx.pid ] || kill -USR1 `cat /opt/nginx/logs/nginx.pid`
        endscript
}

Configuring and running your Rails app

Now comes the easy part – actually running your Rails app. 🙂

Edit your Nginx config file at /opt/nginx/conf/nginx.conf. Add this in:

server {
    listen 80;
    server_name www.your_host_name.com;
    root /path/to/your/rails/app/public; 
    passenger_enabled on;

    # For file uploads
    client_max_body_size 20m;
}

Make sure that the root path points to your application’s ‘public’ directory.

When you copy/deploy your app, run bundle install to install all the gems for the application. Do any database migrations.

Run sudo service nginx restart to restart Nginx. Your app should be running now.

Troubleshooting

Check your nginx logs at /opt/nginx/logs and also your Rails app production.log. Those will give you the most information.

Credits