Recently, I have been dabbling in the Ruby/Rails world for the first time, and as a newcomer there’s lots of new information from many different sources that I thought I would put together for other newbies. After much research and head scratching this is the Rails stack that I’ve come up with, minus the database, that will be next. I hopeful this setup will be a rock solid solution, and from what I’ve Googled around it at least appears to consist of proven frameworks and technologies.
Here are the technologies I have chosen:
- Ubuntu 10.10 (Maverick)
- RVM 1.1.8
- nginx 0.8.54
- Phusion Passenger 3.0.2
- Ruby 1.9.2 p136
- Rails 3.0.3
So let me explain a bit about why I chose each item in the list above. I chose Ubuntu as the OS because I want more Unix/Linux experience, seems to be one of the more popular Linux distros out there and its the Linux OS that I have the most familiarity with. Next is Ruby/Rails, I chose the latest versions of each because even though I don’t have a specific application in mind to build yet, I might as well spend my time learning the latest and greatest today so if and when I do build my next app in Rails, those versions will be the norm. Moving on, I kind of stumbled onto RVM during my research and glad I did. I love it’s ease of use, ability to setup multiple environments without worrying about version conflicts, and it’s integration with Capistrano (future blog post). Nginx is light-weight, both in features and memory utilization, fast, I like the configuration syntax and seems to be gaining popularity. Lastly, Phusion Passenger was chosen because it’s recommended here on rubyonrails.org.
So lets get started and put the pieces together.
Setup a new user account.
Create a new user account, change the password and then add the new user account to sudoers file. The rails application will run as this user.
$ sudo useradd -s /bin/bash -m app-user # add user $ sudo passwd app-user # change password $ sudo /usr/sbin/visudo # edit sudoers file # Add line below just below 'root ALL=(ALL) ALL': app-user ALL=(ALL) ALL
From here on out we’ll be executing the installation as this user.
$ su app-user
Install RVM
Install the dependencies needed for RVM and then install.
$ sudo apt-get install git curl build-essential vim libcurl4-openssl-dev $ bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
Brilliant! Can’t get any easier than this.
Update ~/.bashrc file (remember this is the app-user’s .bashrc file).
$ vim ~/.bashrc # This snippet should placed at the end of the .bashrc file. [[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.
Exit as app-user and then su app-user again to load rvm into the shell session.
Install Ruby prequisites
Double-check what the Ruby dependencies are using:
$ rvm notes
Install the dependencies
$ sudo apt-get install build-essential bison openssl libreadline6 libreadline6-dev \ curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev \ sqlite3 libxml2-dev libxslt-dev autoconf
Install Ruby
Install Ruby using rvm.
$ rvm package install zlib $ rvm package install openssl $ rvm install 1.9.2 --with-zlib-dir=$rvm_path/usr --with-openssl-dir=$rvm_path/usr
Create GemSet
$ rvm --create use 1.9.2@myapplication $ rvm --default use 1.9.2@myapplication $ ruby -v # test it
Install Phusion Passenger
$ gem install passenger
Install nginx using the passenger installer
Download and then extract nginx source, remember this location. The passenger installer can download it for you as part of option 1 during the install, but I chose option 2 so that I can supply extra arguments to the nginx installer.
$ wget http://nginx.org/download/nginx-0.8.54.tar.gz $ tar xvf nginx-0.8.54.tar.gz $ rvmsudo passenger-install-nginx-module # rvmsudo is required in order to install nginx to /opt/nginx
Create an Upstart job to start nginx at boot time. Create a new file /etc/init/nginx.conf and then add the following:
$ sudo vim /etc/init/nginx.conf
The complete contents of the nginx.conf file are:
description "Nginx HTTP Server" start on filesystem stop on runlevel [!2345] respawn exec /opt/nginx/sbin/nginx -g "daemon off;"
Next, we’ll want to restart to verify our upstart script works.
$ sudo shutdown -r now
Verify nginx is up and running
$ sudo initctl list | grep nginx
You should see:
nginx start/running, process 678
…Or use a browser and visit http://localhost
Install Rails 3
su back in with app-user if you’re not already.
$ gem install rails --version 3.0.3
Create a sample rails application to verify our setup
$ sudo mkdir /rails_apps $ sudo chown app-user:app-user /rails_apps $ cd /rails_apps $ rails new myapplication $ cd /rails_apps/myapplication $ bundle install $ rails generate scaffold Post name:string title:string content:text $ RAILS_ENV=production rake db:migrate
Configure your rails app to work with nginx/passenger
Open nginx.conf to configure nginx
$ sudo vim /opt/nginx/conf/nginx.conf
Change the second line for the user to ‘app-user’
You will then need to add a server block looking similar to this:
server {
listen 80;
server_name localhost;
root /rails_apps/myapplication/public; # <--- be sure to point to 'public'!
passenger_enabled on;
}
Restart nginx once again
$ sudo service nginx restart
Use a browser to test app
You will most likely see an error in /www/my-application/log/production.log that says something like “attempt to write a readonly database”. You will need to figure out your permissions with the /my-application/db/production.sqlite3 directory and file. However, if you’re rails app is configured to use a different rdms other than SQLite like MySQL of PostgreSQL, this will probably won’t be an issue.

January 8th, 2011 3:04 pm
[...] This post was mentioned on Twitter by kayne lee. kayne lee said: RVM + Rails 3 + nginx + Phusion Passenger http://bit.ly/gUoCJm [...]
January 16th, 2011 6:48 pm
Nice, beautiful, thank you for this.
January 26th, 2011 11:12 am
Thank you very much!
January 26th, 2011 1:02 pm
Thanks.. you have put a lot effort for this and its nice of you to share this.. It saved me a lot of time !!
March 22nd, 2011 11:53 pm
Any idea why I still get the blank screen “Welcome to nginx!” after restart with rails app?
Please help.
Thanks,
Luan
March 23rd, 2011 7:32 am
I have no idea why, can you post the contents of your nginx.conf?
March 23rd, 2011 5:44 pm
Hi Russell,
I commented out
location / {
root html;
index index.html index.htm;
}
from my nginx.conf and it worked. Either I need to change this link into my app or remove it all together. Did you have this in your nginx.conf. It came with the default installed.
Thanks a lot for your help.
Luan
March 23rd, 2011 1:48 pm
Hi Russell,
Sorry for a long nginx.conf. I didn’t create a separate user as your post, but I use my user which is luan. Here is my nginx.conf
When I go to browser, http://127.0.0.1 or http://localhost: I only get
“Welcome to nginx”. Thanks for your help.
####################################################
#user nobody;
user luan;
#user www-data;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
passenger_root /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.5;
#passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.2-p180/ruby;
passenger_ruby /usr/local/bin/passenger_ruby;
include mime.types;
default_type application/octet-stream;
#log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
# ‘$status $body_bytes_sent “$http_referer” ‘
# ‘”$http_user_agent” “$http_x_forwarded_for”‘;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
root /opt/rails/myapplication/public; # <— be sure to point to 'public'!5
passenger_enabled on;
#rails_env development;
#rack_env development;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
…
July 1st, 2011 7:32 am
I performed the same steps on a VPS – http://46.102.244.155/ But I keep on seeing the default steps. Any idea what needs to be done ? My conf file looks like – https://gist.github.com/1058440
(I am using user root here)
August 4th, 2011 5:01 pm
Very nice walkthrough. It really helped me a lot. Thanks!
August 17th, 2011 7:10 pm
Thanks for this. Very useful and precise. Saved me a lot of time.
I used Ubuntu 10.10 on Amazon. And it worked like a charm.
I changed a couple of things:
a) when compiling nginx, I specified the option: –with-http_ssl_module
b) I attached a volume to the instance and mounted it at /mnt/data-store/
And stored the rails_apps folder there: /mnt/data-store/rails_apps/
Also, changed nginx conf to point to that folder.
August 22nd, 2011 7:11 pm
[...] http://blog.bigrocksoftware.com/2011/01/07/rvm-nginx-passenger-rails-3/ [...]