Tuesday, January 31, 2012

My twelve-factor app development environment (Unicorn and Pound)

I've been hugely influenced by the twelve-factor app manifesto written by Heroku. I really like building apps on Heroku and think it's pretty great for prototyping things, because it totally abstracts the need to think about devops in the early stages of a project. I don't think Heroku is a panacea (I don't have experience running something large on it), but it's great for getting something going quickly.

That manifesto illustrates how you end up building your app if you launch it on Heroku. I've found the  principles greatly increase my productivity no matter what platforms I'm using. One thing that did take me a little while to figure out: most of my apps are SSL-only, and I always want to interact with them over SSL in my development environment because odd things can creep up in production if you never test SSL locally. (Most of the advice that Rails blogs give always point you towards shutting off SSL in development mode which seems crazy to me)

At first I couldn't quite figure out how to make SSL work while complying with factor 7, Port Binding. I was still using Phusion Passenger with SSL configured as I described in this very old article (which still gets a lot of traffic).

Now here's what I do. I run the Pound reverse proxy using this configuration:

# http://lvh.me
ListenHTTP
  Address 127.0.0.1
  Port    80

  Service
    BackEnd
      Address 127.0.0.1
      Port    8080
    End
  End
End

# https://lvh.me
ListenHTTPS
  Address 127.0.0.1
  Port    443
  Cert    "/usr/local/etc/pound.pem"
  AddHeader "X_FORWARDED_PROTO: https"

  Service
    BackEnd
      Address 127.0.0.1
      Port    8080
    End
  End
End

The /usr/local/etc/pound.pem file is a locally-generated, locally-signed SSL certificate.

When I want to view an SSL-only app in my local browser, I just start Unicorn (my app container of choice) which defaults to port 8080. Then I visit https://lvh.me which is helpfully set to the loopback address 127.0.01. That hits Pound, which terminates the SSL connection (after a warning about the self-signed certificate), and proxies the web request to Unicorn.

This is very similar to what happens when the app runs in production on Heroku's systems, except that they use a Procfile in the root directory of the app to configure Unicorn. Per factor 7, it allows Heroku to bind my Unicorn instance to any arbitrary port:

web: bundle exec unicorn -p $PORT -c config/unicorn.rb

Monday, January 30, 2012

Simple Resque lets you send Resque jobs from one codebase to another

I just released a small gem called simple_resque which abstracts a pattern that's become very common in my recent projects. I like using Resque as a job queue to move as much work out of the web application as possible. Unlike the usual Resque setup, I never put the workers in the same codebase as the web app. I like to keep the asynchronous parts of the app completely separate from the code that services web requests.

This required some hacking since Resque expects you to pass a Ruby class constant for the worker, but the webapp doesn't have those classes defined. simple_resque provides a thin wrapper over Resque's push method that mimicks the way Resque.enqueue works, but doesn't require you to use a class constant.

For more details check out: https://github.com/subelsky/simple_resque

Thursday, January 12, 2012

OtherInbox acquired by ReturnPath

I've written on and off about my experiences using Ruby and JavaScript and other technologies to build OtherInbox, the company I cofounded with Josh Baer. Today I'm happy to announce that the company has been acquired by ReturnPath

It was a great ride, and I learned a ton. Congratulations to the whole team! 

I am now starting another round of the entrepreneurial cycle and have started working on something new and very cool. As usual I don't plan to announce details until the business is up and running and ready for new customers. So stay tuned!