Isnor Creative
Isnor Creative Blog
Ruby, Ruby on Rails, Ember, Elm, Phoenix, Elixir, React, Vue

May 19, 2009

My Recipe For Capistrano/Git Rails Deployment on Webfaction

The joys of Capistrano have long eluded me. I was well aware of the easy life of instant deploys that it promised, but getting it up and running on my WebFaction account proved an insurmountable task that always saw me giving up in frustration, I didn’t even try getting things going with Vlad. Every time I created a WebFaction account I bravely attempted to get Capistrano running again, and every time I failed and gave up. Maybe the problem had to do with me not being willing to fork out the cash for a Github account – I was trying to deploy instead from my local Github repo. Or maybe it had to do with Capistrano’s vague/non-existent error messages; I had a feeling that the software was vague due to the fact that it was created and intended for an elite group of intelligent professionals, not troglodytic hackers like myself.

The first time I created a Hosting Rails account I found getting things going with Git and Capistrano were incredibly easy. And the benefits of Capistrano were immediately discernible. Pushing changes were suddenly a few words and a return key away instead of an exercise in annoyance. The writeup I followed to get Capistrano working on Hosting Rails was based on the idea of deploying from a Git repo on the WebFaction account itself.

It occurred to me that this could be the key to finally getting Capistrano and Git working for me on WebFaction…. 24 hours later, and after endless curses, hair pulling, fists banged on tables and whatnot, I finally got the darned thing playing nice, pretty much.

This is the solution that finally worked for me, based on a combination of resources:

Preliminaries

At the point where you install the mysql gem using the instructions in this article, you will encounter an error. Run this instead: gem install mysql -- --with-mysql-config=/usr/bin/mysql_config

Step 1 - Get Git Going

  • Go to the Git site and copy a link to the latest release, then log in to your WebFaction account using SSH and get it (adjust your actions according to the release): wget http://kernel.org/pub/software/scm/git/git-1.6.5.6.tar.bz2
  • Untar Git: tar -xvjf git-1.6.5.6.tar.bz2
  • Change into the Git directory: cd git-1.6.5.6
  • Configure it: ./configure --prefix=$HOME
  • Make it: make && make install
  • Now test to make sure everything worked by calling the Git version: git version
  • You’ll need to edit .bashprofile and .bashhrc in your Webfaction home folder now to make sure that the Git command line works:

    .bash_profile

    Get the aliases and functions

    if [-f ~/.bashrc]; then . ~/.bashrc fi

    User specific environment and startup programs

    PATH=$PATH:$HOME/bin GIT=/home/me/git-1.6.5.6/

    export PATH export PATH=$GIT:/home/me/ruby1.8/bin/:/home/me/ruby1.8/lib/ruby/gems/1.8/ bin/:$PATH

  • Create a zip archive of your app on your local machine.

  • Go to your home folder, then create a place for your repository on the server:

    cd mkdir git

  • Back on your local machine, copy up your app: scp /path/to/myapp.zip username@domain:~/git/

  • Back on the server, unzip the application, then initialize a Git repository:

    cd git unzip myapp.zip cd myapp git init git add . git commit -a -m “Initial commit.”

  • Back on your local machine, clone the Git repo, then Capify it:

    git clone me@domain:/home/me/git/myapp myapp cd /path/to/myapp capify .

Everything worked this far? Great! On to the next step: the Capistrano recipe…

Step 2. The Capistrano Recipe (myapp/config/deploy.rb)

default_run_options[:pty] = true
ssh_options[:forward_agent] = true
user = 'me'
password = "my_password"
application = 'me'
domain = 'me.com'
set :webfaction_port, "my port number goes here"
set :webfaction_username, "#{user}"
set :user, user
set :domain, domain
set :application, application
set :repository, "#{user}@#{domain}:/home/#{user}/git/#{application}"
set :scm, :git
set :rake, "/home/#{user}/ruby1.8/lib/ruby/gems/1.8/bin/rake"
set :deploy_via, :checkout
set :scm_command, "/home/#{user}/git-1.6.5.6/git"
set :local_scm_command, "git"
set :scm_username, user
set :scm_password, "#{password}"
set :scm_passphrase, "#{password}"
set :use_sudo, false
set :branch, "master"
set :scm_verbose, true
set :git_shallow_clone, 1
set :deploy_to, "/home/#{user}/webapps-releases/#{application}"
set :group_writable, false
set :keep_releases, 4
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
desc "Redefine deploy:start"
task :start, :roles => :app do
invoke_command "/home/#{user}/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 "/home/#{user}/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 "/home/#{user}/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
after "deploy:update", "deploy:cleanup" # OTHER WISE OLD RELEASES WILL NOT BE DELETED EVEN THOUGH KEEP IS SET
view raw deploy.rb hosted with ❤ by GitHub

Step 3. Prepare Your App For Capistrano

Log into your Webfaction account and create a directory called webapps-releases, then empty your webapp folder, save for the autostart, and relink :

cd ~/webapps/myapp
mv autostart.cgi ~/
rm -rf *
mv ~/autostart.cgi .
ln -s ~/webapps-releases/myapp/shared/log ~/webapps/myapp/log

Now you want to edit the last line of your autostart: os.system('/home/me/ruby1.8/lib/ruby/gems/1.8/bin/mongrel_rails start -c /home/me/webapps-releases/myapp/current -d -e production -P /home/me/webapps/myapp/log/mongrel.pid -p MY PORT NUMBER')

Step 4. Final Steps

  • Save the recipe and add it to your Git repo.

    git add . git commit -a -m “Capified.” git push

  • Now your are ready to begin your deployment:

    cap deploy:setup cap deploy:update

Future Deployments

If you’ve got this far without any problems, future deployments might be as easy as comitting your changes and deploying:

git add .
git commit -m 'my latest commit'
git push origin master
cap deploy

Notes

I have had problems with a few gems, namely Hpricot and RedCloth, perhaps because they include non-Ruby files in C and Java etc). I found that the only way to get around these problems was to NOT INCLUDE THEM in the config.rb gem dependencies in my application. Just install them on your WebFaction via gem install hpricot, gem install RedCloth. I think these gems are also causing problems with the standard deploy procedure…. If your app is not working after running cap deploy, you can try running

cap:deploy:restart

or

cap deploy:stop
cap:deploy:start

Solving Restart Problems After Cap Deploy

I have been having problems and found that the procedure that works for me is to modify the capistrano restart procedure to this:

desc "Redefine deploy:restart"
task :restart, :roles => :app do
invoke_command "/home/#{user}/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
invoke_command "/home/#{user}/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
view raw deploy.rb hosted with ❤ by GitHub

Capistrano’s error messages are vague/non-existent as far as I can tell. I finally troubleshot my problems by modifying the capistrano gem itself to print out various parts of its process - eg the revision, the results, the command it was issuing, etc…. you might try doing this, if you’re having problems.

Capistrano Migrations

I have had trouble with Capistrano’s cap deploy:migrate feature, and solved it like this:

# I ADD THIS TO CAP DEPLOY
set :rake, "/home/#{user}/ruby1.8/lib/ruby/gems/1.8/bin/rake"
# AND I ADD THIS TO .bash_profile and .bashrc
export GEM_PATH=/home/YOUR USERNAME/ruby1.8//lib/ruby/gems/1.8
view raw deploy.rb hosted with ❤ by GitHub

javan-whenever

I also had problem getting javan-whenever to update via Capistrano, and after much wrangling I finally started reading through Capistrano’s endless logging and discovered that sh was simply not finding whenever, so this worked for me:

after "deploy:symlink", "deploy:update_crontab"
namespace :deploy do
desc "Write Crontab"
task :update_crontab, :roles => :app do
run "cd #{release_path} && /home/#{user}/ruby1.8/lib/ruby/gems/1.8/bin/whenever --write-crontab"
end
end
view raw deploy.rb hosted with ❤ by GitHub

I am available for Ruby on Rails consulting work – get in touch to learn more.

Gordon B. Isnor

Gordon B. Isnor writes about Ruby on Rails, Ember.js, Elm, Elixir, Phoenix, React, Vue and the web.
If you enjoyed this article, you may be interested in the occasional newsletter.

I am now available for project work. I have availability to build greenfield sites and applications, to maintain and update/upgrade existing applications, team augmentation. I offer website/web application assessment packages that can help with SEO/security/performance/accessibility and best practices. Let’s talk