The Source for Java Technology Collaboration


Rails Virtual Appliance

Ruby on Rails application developers can use a Rails virtual appliance to easily deploy their Rails application without having to know the complex details of configuring the Rails environment. This document outlines the steps involved in configuring a Rails production environment on a Solaris distribution running in a VMware virtual machine running on Mac OS.

The architecture of the appliance consists of a front-end Apache 2 web server for load balancing and a set of Mongrel Ruby web application servers to service Rails requests. There is also a MySql database available for use by the Rails application.

For our demonstration Rails application, we will use the "depot" application from the "Agile Web Development with Rails" book.

Install Base Operating System

  • Create a new Fusion Virtual Machine (VM)
  • Install SXDE in 32-bit mode. See instructions.
  • We should be able to install a smaller version of OpenSolaris but that work is TBD.
  • Don't forget to also Install the VMware tools so that cut and paste and mouse behavior work. See the VMware manual for instructions.

Configure Networking on the VM

  • Configure the network interface to "Bridged" so it can be accessed from other hosts.
  • Login as "root" and open a terminal window. I also run "bash" so I get features such as file completion. Use commands such as the following to configure the network interface's IP address. Make a note of the VM's IP address.
    • ifconfig -a
    • ifconfig vmxnet0 dhcp drop
    • ifconfig vmxnet0 dhcp start

Install Application Software

The CoolStack site has prebuilt Solaris packages for some of the components we need. Here we are using CoolStack version 1.2.

  • Download and bunzip2 the following CoolStack packages: CSKruntime_1.2_x86.pkg.bz2, CSKruby_1.2_x86.pkg.bz2, CSKamp_1.2_x86.pkg.bz2. The package output will be installed under /opt/coolstack. As the root user, use "pkgadd -d" to install the above packages. For the CSKamp super package there is a packaging bug so you need to use "pkgtrans" in addition to "pkgadd". For example:
    • pkgtrans CSKamp_1.2_x86.pkg /var/tmp
    • pkgadd -d /var/tmp
    • Select and install only CSKapache2 and CSKmysql32.
  • Create a "rails" user and a "rails" group. An easy way to do this is to use the gnome Administration->Users and Groups tool. Make the default group for the "rails" user be the "rails" group.
  • Initialize the new rails account.
    • In a new terminal window, "su - rails" to login as the "rails" user.
    • Create a new ~/.bashrc file to contain the following line: "export PATH=/usr/local/bin:/opt/coolstack/bin:$PATH".
    • Source the file by executing ". ~/.bashrc".
  • Test the rails install. In the "rails" user terminal window, execute "rails -v" and verify that it prints out the rails version.

  • Download and install "sudo" from sunfreeware.com. Give permission to the "rails" user to "sudo" by adding this line: "rails ALL=(ALL) SETENV: ALL" using this command: "EDITOR=vi /usr/local/bin/sudoedit /usr/local/etc/sudoers".

Configure Remote Login via Ssh

  • On your rails app development machine, lets call this machine "devhost", create a public key pair for ssh if you don't have one already. For example, execute "ssh-keygen -t rsa".
  • On "devhost", login to the VM by running something like: "ssh rails@129.146.81.16". Use the IP address you noted above with the password you set up for the "rails" account. Also, accept the host authentication prompt the first time.
  • While you are still logged in, create a "~/.ssh" directory with mode 700. Create an "~/.ssh/authorized_keys" containing the contents of ~/.ssh/id_rsa.pub on "devhost". Change the mode of the file to 600.
  • Logout and verify that you can login again without using a password. This will make it easier to use Capistrano later because it uses ssh.

Configure MySQL Database

Follow the configuration instructions for the 32-bit coolstack version of mysql which can be found at /opt/coolstack/mysql_32bit/README. This includes creating a "mysql" user and group and initializing the database tables. Use SMF (Service Management Facility) to enable the database server.

Create a database for our Rails application.

  • /opt/coolstack/mysql_32bit/bin/mysql -u root
  • mysql> CREATE DATABASE myapplication;
  • mysql> GRANT ALL PRIVILEGES ON myapplication.* TO 'myapplication'@'localhost' IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
  • mysql> quit

Configure the Apache Load Balancer

TBD.

Enable the apache2 webserver using SMF.

# svcadm enable csk-http

Install Additional Ruby Packages

We next install additional Ruby packages that are not included in the coolstack packages using the RubyGems? package manager. If you are prompted for additional information, choose the latest Ruby version.

$ gem install -y capistrano
$ gem install -y mongrel
$ gem install -y mongrel_cluster

Configure the Rails Application on Devhost

A Rails appliance provides a production-ready platform to deploy a web app into but it does not necessarily simplify the deployment process itself. Here we will use Capistrano to deploy our app into the Rails appliance along with a Subversion repository. For more information, see this link.

Back on the machine "devhost" (I use my laptop), we assume the user has already developed and tested their Rails application locally using the Rails test infrastructure and it is ready to be depolyed into "production" machine. At this point we need additional tools for deployment so make sure the capistrano and mongrel_cluster gems are installed locally (see above steps). For this demo, we will use a pre-developed app so download the "depot" Rails application and extract "depot_r.zip" into a temporary directory on "devhost". Import "depot_r" into a subversion repository and check out a working copy.

$ svn import /tmp/depot_r https://vadev-rails.googlecode.com/svn/trunk/depot_r -m "initial import"
Adding         /tmp/depot_r/test
Adding         /tmp/depot_r/test/unit
Adding         /tmp/depot_r/test/unit/product_test.rb
Skipped '/tmp/depot_r/test/unit/.svn'
...
$ svn co https://vadev-rails.googlecode.com/svn/trunk/depot_r
A    depot_r/test
A    depot_r/test/unit
A    depot_r/test/unit/product_test.rb
...

Edit the config/database.yml file so that the "production" entry matches with the database setup from above.

production:
  adapter: mysql
  database: myapplication
  username: myapplication
  password: some_pass

Next generate the mongrel cluster configuration file in your local application on "devhost" which will eventually be deployed to the Rails appliance. The following command will write a configuration file in "config/mongrel_cluster.yml". This sets up the cluster to run in production mode as the user "rails" and will start 3 mongrel servers listening on ports 8000, 8001, and 8002.

$ cd depot_r
$ mongrel_rails cluster::configure -e production -p 8000 -a 127.0.0.1 -N 3 -c /export/home/rails/depot/current --user rails --group rails

We next need to configure Capistrano to deploy our Rails app to the Rails appliance. In the application root directory,

$ capify .

Edit "config/deploy.rb" so that it looks similar to the following.

set :application, "depot_r"
set :repository,  "http://vadev-rails.googlecode.com/svn/trunk/#{application}"

set :runner, "rails"

default_environment["PATH"] = "/opt/coolstack/bin:/usr/local/bin:/usr/bin"
ssh_options[:username] = 'rails'

# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, "/var/www/#{application}"
set :deploy_to, "/export/home/rails/#{application}"

# If you aren't using Subversion to manage your source code, specify
# your SCM below:
# set :scm, :subversion

set (:target) do
  Capistrano::CLI.ui.ask "Target host: "
end
role :app, "#{target}"
role :web, "#{target}"
role :db,  "#{target}", :primary => true

Add a "spin" script to your app to start the cluster of Mongrel servers. The following script will start 3 mongrels starting at port 8000.

$ echo 'script/process/spawner -p 8000 -i 3' > script/spin
$ chmod +x script/spin

You can run your Rails tests at this point. Then check in your changes into the repository.

$ svn status -u
?                   Capfile
?                   config/mongrel_cluster.yml
?                   config/deploy.rb
M               6   config/database.yml
?                   script/spin
Status against revision:      6
$ svn add Capfile config/mongrel_cluster.yml config/deploy.rb script/spin
A         Capfile
A         config/mongrel_cluster.yml
A         config/deploy.rb
A         script/spin
$ svn ci -m "Changes for deployment"
Adding         Capfile
Sending        config/database.yml
Adding         config/deploy.rb
Adding         config/mongrel_cluster.yml
Adding         script/spin
Transmitting file data ....
Committed revision 7.

Deploy the Rails Application

Now you are ready to deploy the app with Capistrano.

$ cap deploy:setup
  * executing `deploy:setup'
  * executing "umask 02 && mkdir -p /export/home/rails/depot_r /export/home/rails/depot_r/releases /export/home/rails/depot_r/shared /export/home/rails/depot_r/shared/system /export/home/rails/depot_r/shared/log /export/home/rails/depot_r/shared/pids"
    servers: ["129.146.84.176"]
    [129.146.84.176] executing command
    command finished
$ cap deploy:cold
  * executing `deploy:cold'
  * executing `deploy:update'
 ** transaction: start
...
$ # Change your app on "devhost" 
$ cap deploy

A "cold" deploy is done the first time, in the future you can make a change on "devhost", test it, check in the code, and execute "cap deploy".

From a remote browser you can navigate to http://129.146.84.176:8000/store or http://129.146.84.176:8000/admin to access the application.

Updates

  • 2007-11-30
  • 2007-11-28 Finished documenting final steps
  • 2007-11-14 Initial version

-- EdwinGoei

Topic RailsVirtualAppliance . { Edit | Ref-By | Printable | Diffs r11 < r10 < r9 < r8 < r7 | More }
 XML java.net RSS

Revision r11 - 01 Dec 2007 - 02:55:27 - EdwinGoei
Parents: VADev?