In this conclusion to a five-part series on application deployment with Ruby on Rails, you'll learn how to create and use the Capistrano Deployment recipe. This article is excerpted from chapter 12 of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).
Application Deployment with Capistrano (Page 1 of 2 )
Creating the Capistrano Deployment Recipe
Capistrano scripts are called deployment recipes and are written in a custom Ruby domain-specific language. Although Capistrano allows you to use the full power of the Ruby language, you probably won’t need it, as Capistrano comes with a set of configurable built-in tasks that can be used for the most common requirements. Let’s take a quick look at the components of a deployment recipe before we create the Emporium deployment recipe.
Understanding Deployment Recipe Components
The deployment recipe consists of tasks, roles, and variables, which can be customized for your production environment.
Capistrano allows you to assign roles to servers. For example, all servers running MySQL are assigned the dbrole, servers running LightTPD are assigned theweb role, and the servers running the FastCGI processes are assigned theapprole.
Roles allow you to target tasks to be run only on servers having a specific role. Roles can be defined in the deployment recipe, as shown here:
role :web, "www.emporium.com" role :app, "app1.emporium.com", "app2.emporium.com" role :db, "db.emporium.com"
The lead developer of Capistrano and Rails core team member, Jamis Buck, embraced the familiar “convention over configuration” rule when writing Capistrano. For example, Subversion is the default version control system, but you can change it to any of the supported ones by modifying a variable in the deployment recipe. You can also declare your own variables and use them in custom tasks. For example, the following lines set the application name to Emporium and the Subversion repository URL to svn://localhost/emporium/trunk.
set :application, "Emporium" set :repository, svn://localhost/emporium/trunk
Capistrano comes with a set of predefined variables. The following are three of the more commonly used variables:
application: The name of your application, such as Emporium.
repository: The location of your application’s source managed by a version control system, such as a Subversion URL:svn://localhost/emporium/trunk.
user: The name to use when logging in to the remote server. Note that Capistrano uses the same name when logging in to all servers. This means that the user must exist on all servers.
Capistrano has a set of built-in tasks that can be used to perform work on the remote server. The deploytask, for example, installs and deploys a new version of your application on the remote machine. Thedeploy task itself calls therestarttask to restart FastCGI processes and other tasks to complete the deployment.
You can also add your own custom tasks to the deployment recipe. Tasks are written in Ruby. For example, you could create a task that runs themysqldumpcommand on the remote machine, as shown in this example:
task :backup_production_database do run "mysqldump -uemporium -phacked emporium_production >>➥ /var/emporium/production_backup.sql" end
You can get a list of all available tasks by executingrake remote:show_tasks.
A task is run on all servers by default. Specify roles to run a task on a specific server or group of servers.
Generating the Deployment Recipe
The first thing you need to do is create the deployment recipe, by applying Capistrano to your application. To do this, execute thecap --apply-tocommand on your local machine:
$ cap --apply-to /home/george/project/emporium Emporium
The command creates two files:deploy.rbis your deployment recipe, andcapistrano.rakeis an extension torakethat allows you to run all the tasks in your deployment recipe withrake. If you runrake -Tnow, you can see that Capistrano added a lot of new tasks, some of which are shown here:
Now that you have the deployment recipe, you can start modifying it to fit your environment. First, set the required variables. Openconfig/deploy.rbin your editor and change the required variables section as shown here:
# ============================================================== # REQUIRED VARIABLES # ================================================================ set :application, "emporium" set :repository, "svn://localhost/emporium/trunk"
Theapplicationvariable is used when creating the directory structure. Therepositoryvariable should be set to point to your Subversion repository.
Next, define roles. Recall that we have the web, application, and database servers deployed on the same machine, so define the three different roles shown in this example (remember to change the IP address to fit your environment):
# ================================================================ # ROLES # ================================================================ role :web, "192.168.0.1" role :app, "192.168.0.1" role :db, "192.168.0.1", :primary => true
We can now target a command to be run on the web, application, or database server. We can also add servers to the environment, and the deployment of the application would still remain the same; only the configuration would change. For example, to add two more application servers to the environment, we might change the configuration as follows:
role :app, "192.168.0.1", "192.168.0.11", "192.168.0.12"
Also note that we have set the one and only database server to be the primary server, so that we can run migrations on it.
Our particular production environment requires some modifications to the Capistrano default settings, so change the optional settings section as shown here:
# ================================================================ # OPTIONAL VARIABLES # ================================================================= set :user, "rails" # defaults to the currently logged in user set :spinner_user, 'rails' set :svn_username, "svn" set :svn_password, "hacked"
By default, Capistrano will take the username that you used to log in to the machine you are running Capistrano from and use it to log in to the remote system. So, for example, if you logged in asgeorgeto your workstation, Capistrano would use that username. You usually want to have one dedicated user for deploying applications to production, and this is most likely not the same as your own username. By specifying theuservariable, we are telling Capistrano to use therailsuser, which we created earlier, to log in to the remote system.
Recall that the FastCGI processes will be started by the spinner script (script/spin) that we created earlier. By default, Capistrano is configured to start the spinner script with theappusername. But we also want the spinner process to run as therailsuser, so we have addedspinner_userto the optional variables section.
svn_usernameandsvn_passwordare used by Capistrano to log in to the Subversion repository when checking out the code. Change them as appropriate.