In which we host a Facebook/Rails app on our local machine and avoid the deploy/test cycle.
code
Make a file config/facebook.yml to hold your settings:
--- development: your_username: facebook: key: 08192fc4c5916a75f3014c130ab241073 secret: 62c551acccde773e011456957aab0f6f port: 10000 developer_twos_username: facebook: key: "" secret: "" port: 10001 host: yourapp.yourserver.com
No, those aren’t my real keys. But you get the idea.
Now, add to config/environment.rb:
FACEBOOK_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/facebook.yml")[RAILS_ENV] FACEBOOK_CONFIG.merge!(FACEBOOK_CONFIG[ENV['USER']] || {})
This lets individual developers override any global setting by adding the key under their username.
Now, install this rake task in lib/tasks/tunnel.rake:
namespace "tunnel" do desc "Start a reverse tunnel from FACEBOOK_CONFIG['host'] to localhost" task "start" => "environment" do puts "Tunneling #{FACEBOOK_CONFIG['host']}:#{FACEBOOK_CONFIG['port']} to 0.0.0.0:3000" exec "ssh -nNT -g -R *:#{FACEBOOK_CONFIG['port']}:0.0.0.0:3000 #{FACEBOOK_CONFIG['host']}" end desc "Check if reverse tunnel is running" task "status" => "environment" do if `ssh #{FACEBOOK_CONFIG['host']} netstat -an | egrep "tcp.*:#{FACEBOOK_CONFIG['port']}.*LISTEN" | wc`.to_i > 0 puts "Seems ok" else puts "Down" end end end
The rake task opens an SSH connection to our server and forwards a port on it to our local box. This will work no matter what kind of NAT or proxy you are behind, as long as you can access your server via SSH.
server setup
Your server’s /etc/ssh/sshd_config file must contain the following line:
GatewayPorts clientspecified
facebook setup
Have each developer setup a Facebook app for themselves, and set the callback url to be their port on your server:
usage
Now, whatever computer you are on, just run rake tunnel:start and Facebook will be able to see your local machine on port 3000. Check that it’s up with rake tunnel:status.
If you’re on an unreliable network, you may want to make a cronjob to keep the tunnel alive.
further resources
Not many people are discussing how to develop a Facebook/Rails app in a sane way, so I might make a series of these “best practice”-style things. The best resources right now are:
- the Facebook Rails wiki page, which includes a somewhat-functional sample app
- Thoughtbot’s Fist in your Facebook article
- The RFacebook forum
Liverail also has a tutorial, but it assumes you know nothing about Rails, so it’s kind of a drag.
Sorry for being a bit of a drag. ;-)
No, but really it was supposed to be a tutorial from scratch, so it needed everything. I tried not to explain all the Rails stuff too much though.
Anyway, very cool solution to a big problem in developing FBML applications.
PS. I love how your code boxes work on rollover.
As a small improvement, you might want to use Autossh instead of a cronjob job to keep the tunnel up:
autossh is a program to start a copy of ssh and monitor it, restarting it as necessary should it die or stop passing traffic.
On Mac, it’s available as a Port:
Cheers.
Stuart: Nothing personal meant; I’m sure it’s a good article for those just starting out.
Dirk: autossh is working well for me; thanks for the tip.
This is a nice tip that complements the other tutorials out there quite well. One thing, the exec method doesn’t work on my system, but replacing it with system did the trick.
Evan – thanks for posting this. Unfortunately, I’m a newbie on rails and I need to ask some dumb questions in order to get a local testing environment up & running (configuring it all with DreamHost is turning into a real brain teaser).
This is all related to the facebook.yml;
– development; is this the name of the local development database, i.e. in relation to Stuarts’ tutorial, it would be socialrecipes_development?
– your_username: is this our mysql username?
– host: I’ve been unsuccessfully trying to configure my DLink router to forward requests on our external IP to my machine on the network (it’s bizarre – it should be working), but I’m under the impression that I’ll need to configure this in order to fix the host name. Am I on the right track?
Evan, super useful post, thanks very much. Has way sped up my devlopment, once I got things working.
In case anyone else is as slow as I am, once you edit sshd_config, you have to restart the ssh server for the new setting to take effect (‘sudo /etc/init.d/ssh restart’ on ubuntu).
Neil, I think ‘your_username’ in facebook.yml should be the unix username for the environment in question, ie, the unix user on your development box, in the example (I also added a ‘production’ section to my facebook.ym, since I don’t have a dev box other than my local env). That seems to work for me.
As for the host, that should be the host that you want forwarding to your local env. If I understand things correctly, you shouldn’t have to be messing with your router—the whole point of this procedure is to avoid that. I think.
Very cool, just looking into Rails and Facebook and you have provided some great information. The web needs more of you, let the cloning commence.