Running PrivatePub/Faye Standalone in Heroku for Free
PrivatePub is an awesome gem by the renowned Ryan Bates of RailsCasts fame. It provides an easy way to use Faye as a pub/sub 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 as a standalone Rack application on Heroku. This allows you to run PrivatePub in a web dyno instead of a worker, making maintenance easier (by separating repositories/codebases) and saving on hosting costs as a side effect.
Heroku is well known in the Ruby and Rails community as a top-of-mind cloud hosting platform. One of the biggest benefits of Heroku for developers is that it provides—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 in here is the Rack application deployment capability.
# 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 on 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 defines 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 don’t play well with running the server in development mode. So if you’re developing locally, you’d need to pass -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 for your environment. I prefer to make sure my deployment target mimics my development environment as much as possible, so I include it.
Another caveat: Heroku does not support WebSockets yet, so Faye will fall back to long-polling. This may or may not be a deal breaker, as this is in fact desirable behavior—long-polling ensures that your application is supported even by not-so-current browsers.