 |
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
|