Running PrivatePub/Faye Standalone in Heroku for Free
PrivatePub is an awesome gem by the renowned Ryan Bates of Railscast fame. It provides an easy way to use Faye as a pubsub provider. Watch this episode to see it in action.
You don’t have to bundle the gem with a Rails application though; you can deploy PrivatePub standalone as a rack application in Heroku. This allows you to run PrivatePub in a web dyno instead of a worker, allowing for easier maintenance (separation of repositories/codebases) and as a side effect, save on hosting costs.
Heroku is well known in the Ruby and Rails community for being the top-of-the-mind platform when it comes to cloud hosting. One of the biggest benefits of Heroku for developers is that they provide – per application – your first web dyno for free. It’s great for trying out new ideas and services without having to shell out money for a hosting provider.
Heroku supports a number of languages (including Ruby) and a number of deployment options. What we’re interested here is the Rack application depoyment capbility.
# config.ru
# Run with: rackup private_pub.ru -s thin -E production
require "bundler/setup"
require "yaml"
require "faye"
require "private_pub"
Faye::WebSocket.load_adapter('thin')
PrivatePub.load_config(
File.expand_path(
"../config/private_pub.yml", __FILE__
), 'production'
)
run PrivatePub.faye_app
# config/private_pub.yml
development:
server: "http://localhost:9292/faye"
secret_token: "secret"
test:
server: "http://localhost:9292/faye"
secret_token: "secret"
production:
server: "http://example.com/faye"
secret_token: "secret"
signature_expiration: 3600 # one hour
# Gemfile
source 'https://rubygems.org'
ruby "2.0.0"
gem 'faye'
gem 'private_pub'
gem 'thin'
These three files are really all you need to start your PrivatePub standalone server in heroku. You’ll notice a few changes from the original instructions.
rails g private_pub:install
will create a private_pub.ru
rackup file in your app folder. Since heroku by default will define a web process type at deploy time with the following parameters:
web: bundle exec thin start -R config.ru -e $RACK_ENV -p $PORT
I simply renamed the file to config.ru
. You don’t need the rest of the Rails application to run PrivatePub (but you still need Rails to use the client portions).
One caveat: Rack and Faye doesn’t play well with running the server in development mode. So if you’re developing locally, you’d need to make sure you pass in -E production
to thin. You’d also most likely need to copy the same secret_token
for the development
and production
environments.
The second line of the Gemfile
is a bundler
directive only available in version 1.2.0 and above. This is used by Heroku (and even by rvm) to select the ruby version they will use for your environment. I prefer to make sure my deployment target mimics my development environment as much as possible so I throw that in there.
Another caveat: Heroku does not support WebSockets yet, so Faye will fallback to long-polling. This may or may not be a deal breaker, as this is in fact a desirable behavior – long-polling ensures that your application is supported even by not-so-current browsers.