Capistrano

Capistrano automates the deployment, migration, upgrades and rollbacks of your Rails applications.

= Getting Started =

This assumes you are deploying your rails application to your DreamHost server for the first time. See Ruby on Rails for more information.

Set up sub-domain

 * 1) Domains > Manage Domains > Add new domain / sub-domain. (This will take a while to "cook" in the background, so do it first!)
 * 2) * Enable Passenger
 * 3) * append /current/public instead of just the default web directory. (Passenger suggests "/public"; the DH default is simply the domain name.)
 * 4) ** USE: newapp.yourdomain.com/current/public
 * 5) ** and NOT: newapp.yourdomain.com or newapp.yourdomain.com/public
 * 6) After DNS allows access to your http://newapp.yourdomain.com domain, manually delete the /current/public and /current directories that were created by DH.
 * 7) * This is so that later in this tutorial, cap deploy can create a symlink to /current</tt>, allowing Capistrano and Subversion to live happily together. Thanks to topfunky.com for the troubleshooting tip!

Set up new database

 * 1) Goodies > MySQL (This will also take a while to "cook")
 * 2) * Optionally, follow rails conventions for MySQL and create the dbname newapp_production</tt>.
 * 3) * Setup a server for the db: mysql.yourdomain.com</tt> (Rails calls this the host).
 * 4) * Take note of the dbname, username and password you setup, as you'll need this in your database.yml</tt>

Your database.yml</tt> file should look something like this:

development: # [...your development settings for local machine ...] test: # [...your test settings for local machine ...] production: adapter: mysql encoding: utf8 database: newapp_production #following rails db naming convention username: newapp_dbo_user password: newapp_dbo_pass host: mysql.yourdomain.com port: 3306 #not necessary since its the standard mysql port

Notes:

By default your database.yml often comes generated with a socket connector. Don't use socket for Dreamhost.

Replace/comment out the socket: and add the host (mysql server name setup in the panel) and port number: host: mysql.yourdomain.com port: 3306 I included the port here for completeness; but since DH uses the standard mysql port, its technically not necessary.
 * 1) socket: /var/run/mysqld/mysqld.sock

Git
Deploying to DreamHost using Capistrano & Git

Many of the instructions for using Capistrano are Subversion specific. Through much trial and error, I got Capistrano running with GitHub - given the fact that there isn't much information online, I thought I would post some tips and tricks here.

1) The first trick is that new versions of Capistrano (I installed version 2.5.8) use a syntax that DreamHost's default version of Git complains about. The solution is to compile and install Git 1.6.  Fortunately, another DreamHoster has very conviniently posted straightforward instructions on doing just this here: http://blog.toppingdesign.com/2008/04/08/installing-git-on-dreamhost/

2) Now that you have Git 1.6 installed, you need to specifically tell Capistrano which version of git to use, both on the server and locally. Use these lines in your deploy.rb file to do just that:

set :scm_command, "~/packages/bin/git" #updated version of git on  server in user directory

set :local_scm_command, "/opt/local/bin/git" #correct path to local  git

3) Finally, you need to add the path to your installed version of Git 1.6 to your path. Typically, you would add the path to your .bash_profile file.  However, this didn't seem to work for me - instead, for Capistrano I also needed a .bashrc file with your GEM PATH variable and with the path to your installed version of Git 1.6.  Use these lines:

export GEM_HOME=$HOME/.gem

export GEM_PATH=$GEM_HOME:/usr/lib/ruby/gems/1.8

PATH=$PATH:~/packages/bin/

export PATH

Subversion
This step should happen after DH DNS has created your newapp.yourdomain.com and it resolves in your browser. If you do this step before that has happened, you may have to delete your subversion repository and recreate it agian. Unless you intend to let Capistrano create your subversion repository elsewhere, you'll want to establish your subversion repository in Goodies > Subversion in DreamHost's control panel. (You can also set it up at another subversion host, if you wish. It makes sense to do it manually, if the host will not let Capistrano do it.)

Environment Configuration
Important: Read the Ruby on Rails page before you proceed, especially the "To set up Rails on a subdomain" section.

Force Production RAILS_ENV
Previously, it was recommended to uncomment the  line in config/environment.rb</tt>. However, Dreamhost now defaults to 'production' environment, so this is no longer necessary. You can skip this step.

Typically, with a default rails app, the  line comes commented out (#) in config/environment.rb</tt> file. Committing the environment.rb file with the line uncommented will cause havoc on your dev environment each time you update your code from the repository.

If you're using Capistrano, you can cleverly surpass this problem and force 'production' environment during deployment by add the following the task in your Capfile</tt>:

desc "Restarting after deployment" task :after_deploy, :roles => [:app, :db, :web] do run "sed 's/# ENV\\[/ENV\\[/g' #{deploy_to}/current/config/environment.rb > #{deploy_to}/current/config/environment.temp" run "mv #{deploy_to}/current/config/environment.temp #{deploy_to}/current/config/environment.rb" end

Fix Dispatcher Shebang!
Modify the Ruby she-bang lines. Most are fine. The ones in public/dispatch.*</tt> are wrong. Change them to:

#!/usr/bin/env ruby

Sometimes this is not correct. To make sure login the shell and try a "whereis ruby" or run "./dispatch.fcgi" yourself.

Fix .htaccess to use Dispatcher
In public/.htaccess</tt>, change the RewriteRule</tt> for the dispatcher to use the FastCGI dispatcher instead:

RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

Add these rules immediately after RewriteEngine On</tt> to display a maintenance page if it exists on the file system:

RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteCond %{SCRIPT_FILENAME} !^(.+).(gif|jpg|css|js|swf)$ RewriteRule ^.*$ /system/maintenance.html [L]

Automate Deployment with Capistrano ("capify")
From your RAILS_ROOT</tt>, execute the following commands:

$ capify.

The above will create the two files ('Capfile' and 'deploy.rb') inside your rails root, that Capistrano uses to do deployment. The output should look something like this: [add] writing `./Capfile' [add] writing `./config/deploy.rb' [done] capified!

$ svn add Capfile config/deploy.rb

The above line adds the new Capistrano files to your subversion repository.

Edit config/deploy.rb</tt>, setting :application</tt> and :repository</tt> properly. All roles should point to your newly created web host. <tt>:deploy_to</tt> should point to the top-level of the web directory you set up earlier (NOTE: leave <tt>current/public</tt> off the end). On DreamHost's shared hosts, <tt>sudo</tt> can't be used to restart the app. So set <tt>:use_sudo</tt> to <tt>false</tt>. Set <tt>:deploy_via</tt> to <tt>:export</tt> so as not to create a <tt>.svn</tt> in your world-accessible directory.

Your <tt>config/deploy.rb</tt> should resemble:

set :user, 'dhuser' # Your dreamhost account's username set :domain, 'servername.dreamhost.com' # Dreamhost servername where your account is located set :project, 'myapp_name_from_repository' # Your application as its called in the repository set :application, 'myapp.mydomain.com' # Your app's location (domain or sub-domain name as setup in panel) set :applicationdir, "/home/#{user}/#{application}" # The standard Dreamhost setup set :scm_username, 'YOUR_SVN_USERNAME' set :scm_password, 'YOUR_SVN_PASSWORD' set :repository, "http://svn.my_subversion_domain/#{project}/trunk/" role :web, domain role :app, domain role :db, domain, :primary => true set :deploy_to, applicationdir set :deploy_via, :export default_run_options[:pty] = true # Forgo errors when deploying from windows set :chmod755, "app config db lib public vendor script script/* public/disp*" set :use_sudo, false
 * 1) version control config
 * 1) roles (servers)
 * 1) deploy config
 * 1) additional settings
 * 1) ssh_options[:keys] = %w(/Path/To/id_rsa)           # If you are using ssh_keys

Note that the  role specifies where migrations should be run, not where the database is located. That's why the domain should be the one where you have shell access, not your database's domain.

If you've configured a SSH public/private key, you may set the  variable to prevent Capistrano from asking for your password.

If you are using git for source control, be sure to add: set :scm, 'git' set :repository, "git@github.com:your_username/your_project.git" set :deploy_via, :remote_cache set :git_enable_submodules, 1 # if you have vendored rails set :branch, 'master' set :git_shallow_clone, 1 set :scm_verbose, true

Deployment with Capistrano
NOTE: Commit the changes (covered above) in environment, config, and .htaccess / dispatch.* files to your subversion repository prior to deploying.

Prepare deploy environment
First setup server environment by running:

cap deploy:setup

Note:  creates the releases and shared folders. Running cap migrate after might give you a file not found bash error as capistrano tries to cd the current folder; never mind this and simply skip to.

If your repository and  are set up properly, cap deploy will create a current   to the active release folder after exporting it from your repository.

Deploy
After setting up the environment, run a "cold" deployment (first time only):

cap deploy:cold

From then on, to deploy new versions, run:

cap deploy # or: cap deploy:migrate

It might go without saying, but you'll need the command line version of Subversion installed on your development server for the above commands to work.

Maintenance via Capistrano
To revert instantly from a disastrous deployment, run:

cap deploy:rollback

If you need to stop for serious maintenance:

cap deploy:web:disable

Run this when you're ready to face the world again:

cap deploy:web:enable

Update your production server with latest changes from svn:

cap deploy #or: more explicitly... cap deploy:stop cap deploy:update cap deploy:start

Miscellaneous Tasks
To see the tasks available to you, from your <tt>RAILS_ROOT</tt> run: $ cap -T

Will give you a listing of all the tasks available. Run the following for a specific task to get the description:

$ cap -e [taskname]

Keep Generated Files Between Deployments
If your Rails app stores any files on the file system, these aren't kept in SVN so they will need to be kept such that they aren't lost when you re-deploy a new version. The "shared" directory is intended for this, and you can symlink files that you store under "shared" to where they belong within your deployment. You can use a Capistrano event hook to make a task for this in the Capfile so that this works transparently every time you re-deploy.

In this example, files that you want to appear at public/files/uploads are stored under shared/uploads:

desc "Link shared files" task :before_symlink do  run "rm -drf #{release_path}/public/files/uploads" run "ln -s #{shared_path}/uploads #{release_path}/public/files/uploads" end

The directory will now act like it's part of the current deployment, but won't be lost when you re-deploy.

= Gotchas =

Setting up the Migrations
Be sure to use the username and password from the "production" section of your database.yml file to create a new user in the Dreamhost panel: Goodies/Manage MySQL. Check everything is running correctly by running cap deploy:migrations from your local computer, or ssh into the server and run

Default shell
Note that Capistrano assumes your default shell is bash (or perhaps some other sh variant). If you get "if syntax" errors when attempting to deploy, this may be the problem. To fix it, log into the Dreamhost control panel and change your shell to bash.

Freezing Rails vs. Third party code
If you're freezing Rails for deployment (as is wise following the aborted debut of Rails 1.1 at DreamHost) you will need to take special precautions. One way is to set <tt>svn:externals</tt> on <tt>vendor/</tt> to <tt>rails http://dev.rubyonrails.org/svn/rails/tags/rel_1-1-0</tt> (for Rails 1.0) instead of running <tt>rake freeze_gems</tt>. The downside is that your deployments will depend on dev.rubyonrails.org being reachable. Tracking your third party dependencies in your own repositories avoids this problem.


 * Using <tt>svn:externals</tt> on <tt>vendor/</tt>: Ruby on Rails hosting (scroll down to the update)
 * The disadvantage of 'svn:externals'

cap deploy gets stuck 'subversion is asking for a password'
You need to make sure the account you’re using with Capistrano (i.e. your dreamhost account) can access your Subversion repository from the app server where the cap script is running. The solution seems to be to SSH into your dreamhost server and svn co your_repos into a temp directory. It’ll prompt you for the username and password, and once you’ve entered it successfully, it’ll remember it. Then you’ll be able to deploy without any problems.

"svn export" results in 'Killed by signal 15'
If you are pulling your code from your local environment using svn+ssh:// URLs, you will likely get a "Killed by signal 15" error message:

Try running this command from your DreamHost server:

To get around this, you can change the ":deploy_via, :export" to ":deploy_via, :copy" which will do the local checkout and then push a tar.gz file to the DH server. This also works if you're not using DH svn server, or your svn repository is not accessible over the internet (ie: behind a firewall).

= Resources =


 * Feb 2008 - Deploying Ruby on Rails with Capistrano on DreamHost
 * Rails Manual: Capistrano
 * Capistrano 1.1 changes
 * RailsMachine video
 * Nuby on Rails Dreamhost Capistrano Writeup and Task
 * Notes on a June 2006 presentation of Capistrano by Mike Clark
 * Deploying Rails with Edge and Engines to Dreamhost using Capistrano
 * Deploying to Dreamhost with Capistrano
 * How To Deploy your first rails app to Dreamhost using Capistrano in Windows

= SwitchTower =

Capistrano was known as SwitchTower until March 2006. Graeme Mathieson's excellent quick-start guide for SwitchTower (the principal source for this article) can be found here: Using SwitchTower with Ruby on Rails and DreamHost.