Ryan Kanno: The diary of an Enginerd in Hawaii

Everything you've ever thought, but never had the balls to say.

My LinkedIn Profile
Follow @ryankanno on Twitter
My Feed

Update: Using Capistrano 2.5 to deploy Rails 2.3 to Webfaction

Update

Having been a Capistrano user for a few years, I absolutely love sweet, sweet automation. A few months ago, I wrote a blog about how to use Capistrano to deploy to WebFaction. However, since that post, the winds of change have swept through the Rails and Capistrano community with the release of Rails 2.3 and Capistrano 2.5. WebFaction’s Ruby installation precludes you from taking advantage of these great updates, so I’ve come up with a little update to my previous post.


Learn to Change, Change to Learn

To be able to deploy Rails 2.3 with Capistrano 2.5, we’ll first have to jump through a few hoops. Nice, easy hoops, mind you, but still hoops nonetheless.

Your own Ruby installation

You’ll have to install a custom Ruby installation into your WebFaction home directory. By following Step 1 here, you’ll have a working Ruby 1.8.7 installation and RubyGem 1.3. You’ll need these if you want to deploy a Rails 2.3 application. Also, install a version of Mongrel tied to your Ruby installation.

Note: Typically, I like to install custom installations into ~/opt/local/lib/.

Edit Autostart.cgi

You’ll have to make a few edits to a few files from my previous blog post.

Next, open up your favorite editor of choice (*cough*vi*cough*) and edit the autostart.cgi file. Jump to the end of the file and comment out the following line from my previous blog:

1
2
 
# os.system('/usr/local/bin/mongrel_rails start -c /home/<webfaction_username>/webapps-releases/<webfaction_app_name>/current -d -e production -P /home/<webfaction_username>/webapps/<webfaction_app_name>/log/mongrel.pid -p <port>')

and change it to the following:

1
2
 
 os.system('/home/<webfaction_username>/opt/local/lib/ruby1.8/lib/ruby/gems/1.8/bin/mongrel_rails start -c /home/<webfaction_username>/webapps-releases/<webfaction_app_name>/current -d -e production -P /home/<webfaction_username>/webapps/<webfaction_app_name>/log/mongrel.pid -p <port>')

Notice: We’re using the path to Mongrel tied to our custom Ruby installation! This might be different in your installation!

Edit the Capfile

In my previous blog, we placed a custom deploy.rb into the config directory. With the latest version of Capistrano, you no longer need to do this. Rather, place the following into a file called Capfile in the root of your Rails project.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
load 'deploy'
 
set :webfaction_username, "<webfaction_username>"
set :webfaction_db_type, "<webfaction_db_type>"
set :webfaction_db, "<webfaction_db>"
set :webfaction_db_username, "<webfaction_db_username>"
set :webfaction_port, "<webfaction_port (get from autostart.cgi)>"
set :database_yml_template, "database.example.yml"
 
set :application, "test"
set :deploy_to, "/home/#{webfaction_username}/webapps-releases/#{application}"
 
set :scm, :subversion
set :scm_user, "<scm_username>"
set :scm_password, Proc.new { Capistrano::CLI.password_prompt("Subversion password for #{scm_user}: ") }
set :repository, Proc.new { "--username #{scm_user} --password #{scm_password} --no-auth-cache <http://path/to/your/svn/goes/here/>"} 
 
set :user, "#{webfaction_username}"
set :use_sudo, false 
 
set :domain, "<webfaction_domain>"
 
role :app, domain
role :web, domain
role :db,  domain, :primary => true
 
desc "Symlink public to what webfaction expects the webroot to be"
task :after_symlink, :roles => :web do
  run "ln -nfs #{release_path}/public /home/#{webfaction_username}/webapps/#{application}/"
end
 
namespace :deploy do
 
  # Taken from http://jonathan.tron.name/2006/07/15/capistrano-password-prompt-tips 
  # Thanks Jonathan! :)
  desc "Creates the database configuration on the fly"
  task :create_database_configuration, :roles => :app do
    require "yaml"
    set :production_db_password, proc { Capistrano::CLI.password_prompt("Remote production database password: ") }
 
    db_config = YAML::load_file("config/#{database_yml_template}")
    db_config.delete('test')
    db_config.delete('development')
 
    db_config['production']['adapter'] = "#{webfaction_db_type}"
    db_config['production']['database'] = "#{webfaction_db}"
    db_config['production']['username'] = "#{webfaction_db_username}"
    db_config['production']['password'] = production_db_password
    db_config['production']['host'] = "localhost"
 
    put YAML::dump(db_config), "#{release_path}/config/database.yml", :mode => 0664
  end
 
  after "deploy:update_code", "deploy:create_database_configuration"
 
  desc "Redefine deploy:start"
  task :start, :roles => :app do
    invoke_command "/opt/local/lib/ruby1.8/lib/ruby/gems/1.8/bin/mongrel_rails start -c #{deploy_to}/current -d -e production -P /home/#{webfaction_username}/webapps/#{application}/log/mongrel.pid -p #{webfaction_port}", :via => run_method
  end
 
  desc "Redefine deploy:restart"
  task :restart, :roles => :app do
    invoke_command "/opt/local/lib/ruby1.8/lib/ruby/gems/1.8/bin/mongrel_rails restart -c #{deploy_to}/current -P /home/#{webfaction_username}/webapps/#{application}/log/mongrel.pid", :via => run_method
  end
 
  desc "Redefine deploy:stop"
  task :stop, :roles => :app do
    invoke_command "/opt/local/lib/ruby1.8/lib/ruby/gems/1.8/bin/mongrel_rails stop -c #{deploy_to}/current -P /home/#{webfaction_username}/webapps/#{application}/log/mongrel.pid", :via => run_method
  end
end
Note: Change all the values in tags like <webfaction_username>, <webfaction_db>, <webfaction_db_username>, etc. to those values that fit your configuration!
Otherwise, this file in itself won’t do you any good.

Now, you should be able to run the standard Capistrano tasks to deploy your application to WebFaction with the latest version of Rails!

Explanation

Basically, the only thing I’ve done is shown you how to update your version of Ruby, RubyGems, Mongrel, and Capistrano to place nicely in WebFaction. This should allow you to run commands like ‘cap deploy:setup’, ‘cap deploy:update’ on your local machine and update your live code on WebFaction’s servers. Nothing too serious going on here! As always, feel free to use, steal, take, and/or copy anything on this blog. Hopefully somewhere, someone on the Interwebs will find these tips handy!

And if you find anything wrong with these scripts, don’t hesitate to leave a comment or email!

Voila! (Enjoy)

Be Sociable, Share!
  1. [...] If you like to stay on the edge, check out my latest post describing how to use Capistrano 2.5 to deploy Rails 2.3 to Webfaction! [...]

  2. Thanks for the update to your Capistrano tutorial. I have one question though: what would the Capfile look like if we were just using sqlite3?

    thanks.

  3. @Jay -

    If you were just using sqlite3, you’d want to set the following:

    set :webfaction_db_type, “sqlite3″
    set :webfaction_db, “db/name_of_database” (where name_of_database is the name of your db)

    I’m pretty sure if you have empty values for the other options, Rails will just ignore them. :D

  4. If using a public git here is the scm config (shown here for a github account called atc):

    set :scm, :git
    set :repository, “git://github.com/atc/atc.git”
    set :git_shallow_clone, 1
    set :short_branch, “master”
    set :user, “#{webfaction_username}”
    set :use_sudo, false

    To install git on webfaction follow these instructions: http://docs.webfaction.com/software/git.html#installing-git.

    If using git you might want to add a custom path to your Capfile so that Capistrano can find git (by default installed in ~/bin/git). Add something like this line before your task defs:

    default_environment["PATH"] = “/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/#{webfaction_username}/bin:/home/#{webfaction_username}/.gem/ruby/1.8/bin”

    namespace :deploy do

  5. Thanks John for the update!

    I have a git configuration that’s very similar to yours. :D

  6. I upload files and save them to ~/webapps/public/uploads. Everytime I am deploying (using the above method) my uploaded files are getting removed. Is there an easy way in webfaction to save uploaded files to a safe directory or I am doing something wrong. My files are not stored in git.

  7. @John

    Interesting. I don’t expect Capistrano to touch anything other than the directories it sets up (current, releases, shared). Are you uploading into a directory that current is symlinked to – thus, when you deploy again, the current symlink changes and your files disappear into releases?

  8. @ryan

    Yes it was symbolic links. I resolved this by copying over the uploaded files to the new releases directory before recreating the symbolic link in the Capfile.

    Thanks for the idea!

Please leave a reply »

Powered by Wordpress. Stalk me.