Techniques for Efficient Rails App Deployment
You have many good options for deploying Rails web applications. I will discuss only one: a deployment setup that works well on a single server but supports adding additional servers as needed. The setup is composed of the nginx server, the Mongrel server, and the memcached system, which provides a high-performance, distributed memory object caching system that you can use to cache both database requests and web services requests. Rails applications can scale, but as with most web applications, they might have only a few concurrent users. If you add memcached to Mongrel, which is fast by itself, you might be able to put off a more complex deployment until you have more concurrent users.
You should have your Rails application's development settings set for your development PC and the production settings for your Linux server. This is important because this discussion assumes (because you are not using Capistrano) that to deploy a new version of your web application you can simply do an svn update in your server's deployment directory.
Using memcached is as easy as installing a gem:
sudo gem install memcache-client
And adding two lines to your production.rb file:
config.action_controller.fragment_cache_store = :mem_cache_store
config.action_controller.session_store = :mem_cache_store
I do not usually add these to my development.rb file.
Deploying a Cluster on Mongrels on a Linux Server
With Ruby, Gem, and Rails installed on your Linux server (using the same version numbers as on your development PC), you can deploy a Mongrel cluster on it. I will demonstrate how using my CookingSpace.com project as the example. I start by creating a new unprivileged account with the same name as my Rails application. I prefer to name the account after the web application because later I might want to use the nginx web server to service several virtual domain names and I would like the Mongrel cluster for each web application to run under its own account.
Next, I create a deployment directory, create the account, and set ownership of the deployment directory:
sudo mkdir /var/mongrel
sudo mkdir /var/mongrel/cookingspace
sudo /usr/sbin/groupadd cookingspace
sudo /usr/sbin/adduser -r cookingspace -g cookingspace
sudo chown -R cookingspace /var/mongrel/cookingspace
sudo chgrp -R cookingspace /var/mongrel/cookingspace
Now, I use SSH to remotely login to my server using the account cookingspace and pull the latest version of my web application from my subversion server:
svn co svn+ssh://MY_ACCOUNT@MY_SERVER.com/home/svn/svn-repos/cookingspace .
I am using MySQL for my web application so, on my Linux server, I need to set up the databases:
mysqladmin create cookingspace_production --user=root -p
mysqladmin create cookingspace_development --user=root -p
mysqladmin create cookingspace_test --user=root -p
Before going any further, it is a good idea to test the web application running a single Mongrel, but in production mode:
Assuming that this works, we will now install the mongrel_clusters Ruby Gem:
sudo gem install mongrel_cluster
When logged in as user cookingspace, configure three Mongrels and start and stop the cluster to test it:
mongrel_rails cluster::configure -e production -p 3001 -n 3 -a 127.0.0.1 --user cookingspace --group cookingspace