Rake Tasks For Easier Facebook Development

You cannot make it more tedious than it is.

Lets face it. Facebook development is tedious. You do not want to waste more time in endless commit-push-pull-restart loop for smallest code changes. Common development setup is to tunnel traffic from development server to your laptop using ssh tunnel. Here are my Rake tasks for switching between production and development mode.

Facebook Application Stack

I use Sinatra, Thin, Sinbook and DataMapper for all my Facebook development. All static assets are served by Apache. Apache also proxies other requests to Sinatra using mod_rewrite. Proxying is easiest to setup using the following rule in .htaccess file:

RewriteEngine On
RewriteBase /

# Everything not found goes to Sinatra / Rack
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*){REQUEST_URI} [L,P,QSA]

Since Facebook introduced the new Graph API the old REST API will be deprecated. Sinbook is based on the REST API. New developers should start using some alternative Ruby Facebook library. I am currently eyeballing FBGraph and facebook-graphclient.

Basic Setup

I tend to follow use same name for Github repository, hostname of the virtual server and directory name of the application root. Lets assume our new Facebook application is called Foo Bar. Your basic config/deploy.rb for Thin would look like following:

set :application, "foo-bar"
set :repository, "[email protected]:username/#{application}.git"
set :user, "sinatra"
set :server, "#{application}.example.com"
set :domain, "#{user}@#{server}"
set :deploy_to, "/var/www/#{server}"
set :thin_port, 4567
set :thin_socket, nil
set :thin_servers, 1
set :thin_rackup, "#{deploy_to}/current/rackup.ru"

require "vlad"

namespace :vlad do
  desc "Deploy the code and restart the server"
  task :deploy => [:update, :start_app]

Note how I have already added one new task for updating code and restarting Thin with one command:

> rake vlad:deploy

Use Shotgun for Development

Shotgun is real timesaver. With shotgun you do not need to restart webserver each time you change some code. Instead it reloads all code for each request. Lets add Rake task for it in config/deploy.rb.

set :local_port, 9393

namespace :dev do
  system "shotgun --port=#{local_port} rackup.ru"

Tunnel Traffic With AutoSSH

Good way to tunnel traffic between two computers is to use autossh. It starts the ssh tunnel and also monitors and restarts it if the tunnel should die. You only need to install autossh on your development machine. If you're on Mac install with command:

sudo port install autossh

After it has been neatly installed add the following to config/deploy.rb:

namespace :dev do
  desc "Start ssh tunnel."
  task :start_tunnel do
    puts "Tunneling #{server}:#{thin_port} to localhost:#{local_port}"
    system "autossh -M 48484 -nNT -g -R *:#{thin_port}:{local_port} #{server}"

Putting it All Together

It take three steps for changing from production mode to development mode.

  1. Stop application server at production server.
  2. Start development server on laptop.
  3. Tunnel traffic from production server to laptop.

We wanted to switch between development and production mode as easy as possible. It is possible with Rake multitask.

namespace :dev do
  desc "Switch to tunneled development mode."
  multitask :start => [ "vlad:stop_app", "dev:start_shotgun", "dev:start_tunnel" ]

There we have it. Rake tasks for easier Facebook development. You can download the full deploy.rb as gist.


Lets assume you find a bug in your Facebook app. You quickly change to development mode by running following command in your laptop:

> rake dev:start

Now make all the changes you need on your laptop. You can verify your application still works by browsing Facebook as usual. Instead of production server requests are served by your laptop via ssh tunnel. When you are happy with changes stop development mode by pressing ctrl-c. Commit and push your changes to Github. Run Rake task to deploy the changes to production server and restart the application server.

> git commit -a
> git push
> rake vlad:deploy

Posted in Ruby  on 16 Jun 2010.