Showing posts with label rails. Show all posts
Showing posts with label rails. Show all posts

Thursday, October 31, 2013

Fetching your Heroku production database schema into local storage

Updated Aug 23rd, 2014: the old commands I posted here did not work with Postgres 9.3's pg_dump. New commands listed below, including schema migrations dump.

I noticed recently that the structure.sql checked-in to the repository for Staq's main Rails app had fallen slightly out of sync with what was running on our Heroku production database. After a little digging, I came up with the following command. Hopefully this saves you a bit of time - it just mimics what rake db:structure:dump would do for you, but connected to your production database. Will also update the list of schema migrations:

pg_dump -v -i -s -x -O -f db/structure.sql --exclude-table=****** --exclude-table=***** -d DATABASE_NAME -U USER_NAME -h HOSTNAME && pg_dump -v -a -t schema_migrations -x -O -d DATABASE_NAME -U USER_NAME -h HOST_NAME >> db/structure.sql

Monday, January 28, 2013

Invitation to RailsGirls


I'm helping organize RailsGirls Baltimore on 3/2 to introduce computer programming to girls and women in the Baltimore area. No prior experience is required! It's a fun day of learning new skills in a small group with a coach helping you progress through a series of exercises.

Please help me spread the word as much as possible. We'd like to have as many women attend as possible!

Details are here:

http://railsgirls.com/baltimore

Hope to see you there!

Wednesday, October 31, 2012

Setting up Puma & Rails on Heroku

I just moved Adstaq over to Puma this weekend because I want to experiment with a multithreaded server as a way to keep our web serving costs down and our efficiency high. We're already doing this with Sidekiq for our worker code, to great effect, and philosophically I much prefer plain old Ruby threads over other Ruby concurrency solutions. Dave Copeland gave a GREAT talk at RubyConf last year called Don't Fear the Threads which I highly recommend for further inspiration.

It took some trial and error to get Rails talking to Puma and to get everything running on Heroku, so I put the needed code into a gist, embedded below.

I'm monitoring the change on New Relic but so far have not noticed any memory savings vs. Unicorn. But we're also not drowning in traffic right now. Nonetheless I'm glad we're getting some Rails multithreading experience before that happens.

Update: Watsi posted some great instructions for adjusting ActiveRecord's connection pool size.

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

Tuesday, August 30, 2011

How I Would Learn Rails in 2011


An entrepreneur friend just asked me to recommend good resources for learning how to program using Ruby on Rails. Here's what I suggested, in descending order of helpfulness:


Thursday, July 28, 2011

Getting SSL, Capybara, Rails 3, and Devise to work together

I've noticed a lot of Rails blog posts recommending that you only turn SSL on in production and don't try to use it in the test or development environments. This is a monumental mistake, a lesson I learned hard in the early days of OtherInbox: SSL enforcement has a lot of subtleties and corner cases that need to be exercised and tested on a routine basis. As a quick slightly embarrasing example, we had a bug at OIB where flash messages would get swallowed during redirects. It turned out we were accidentally redirecting people to an http:// page, where the flash would be available, but our SSL enforcement code redirected them quickly to https://, and that second redirect ate the flash message. Since we couldn't reproduce the bug on our own machines it was much harder to track down than you would think.

But I know why the bloggers recommend the naive approach though: getting SSL to work offline is a major pain! Right now I'm building a Rails app that enforces SSL on every page. It's all private data (the public-facing site is managed by a separate CMS) so I don't want any page to be accessible over http://. Below is a summary of the code changes I had to make to get this to work. I was mainly guided by this great Collective Idea blog post about Rails 3 SSL that I'd recommend you start with.

It's not hard to get SSL working in development mode if you use an app container like Phusion Passenger. I explained how to do that a few years ago with an Apache-Mongrel setup, but the basic ideas apply.

Update 1/31/2012: I wrote up an easy way to get SSL working with Unicorn and Pound instead of Passenger which is my new preferred way of working. Also check out the Devise wiki for more useful SSL info.

Wednesday, June 8, 2011

Gemfile for Rails 3.x Greenfield

I just started building a new product, and wanted to document my tools of choice in the Gemfile below. I also like to use use Rails Wizard to generate some of the configuration stuff (like making sure generators use Rspec instead of Test::Unit). Normally I would also lock the Rails gems to specific versions but I've been trying this app out with Rails 3.1rc1 so it's easier to let those dependencies float for now.

I'm using 'thin' here because I'm running this on Heroku's new Celadon Cedar stack where you need to bring your own app container (unless you want to use WEBrick).

# gems needed by Rails
gem 'rails', '3.0.8'
gem 'pg'
gem 'sass'
gem 'coffee-script'
gem 'uglifier'
gem 'jquery-rails'

# application gems
gem 'thin', '1.2.11'
gem "haml", "3.1.1"
gem "haml-rails", "0.3.4"
gem 'formtastic', "1.2.4"
gem "foreigner", "1.0.3"
gem "dim", "1.0.0"
gem "authlogic", "3.0.3"

group :development do
  gem "annotate"
end

group :test do
  gem "rb-fsevent", "0.4.0"
  gem "growl", "1.0.3"
  gem "guard-spork", "0.2.0"
  gem "guard-rspec", "0.4.0"
  gem "shoulda-matchers", "1.0.0.beta2"
  gem "capybara", "1.0.0.rc1"
  gem "launchy", "0.4.0"
  gem "timecop", "0.3.5"
end

group :development, :test do
  gem "rspec-rails", "2.6.1"
  gem "silent-postgres", "0.0.8"
  gem "factory_girl_rails", "1.0.1"
end

Tuesday, May 17, 2011

My Presentation Materials

In case you saw me speak at TEDxBaltimore, RailsConf, or Ignite RailsConf over the past few days and would like to get access to my materials, here they are!
Thanks for checking out my blog!

Thursday, February 25, 2010

The Debut of Ignite RailsConf

As a Baltimore-based Rails hacker, someone who loves Baltimore and who loves Ruby on Rails, I was pretty excited to hear about RailsConf coming to town on June 7th. The Rails community here in town is determined to make a great impression on our fellow programmers (especially given the negative reactions by some people to the choice of our city). Along those lines I'm pleased to announce Ignite RailsConf taking place on 6/6/10 at 6 pm at the Sheraton Inner Harbor.

You can propose a talk (due 4/25) or see more details at http://igniterailsconf.com.

Monday, January 18, 2010

Ruby for Startups at Lone Star Ruby Conference 2009

Recently Confreaks posted video from the Lone Star Ruby Conference talk I gave in August, called Ruby for Startups.

I've refined the talk a few times since then but it's still a good representation of my current state of mind about what I've learned about Ruby and about software design while building OtherInbox. Check it out if you'd like to see more! The slides are posted here.


Wednesday, November 11, 2009

Lean startup tools for Rails apps

A few months ago I was invited to dinner with the Geeks on a Plane crew when they stopped in Washington, and had the opportunity to meet one of my heroes, Eric Ries, author of the Startup Lessons Learned blog. His descriptions of lean startup techniques and philosophies have had a big influence on the way I design and build software.

Eric asked me what specific tools Rails developers could use when building a lean startup. Here's a revised version of what I emailed in response, garnered while building OtherInbox and other Rails apps:
  • First and foremost, I find Rails itself to be very useful for building a product for a lean startup; the expressiveness of Ruby and the conventions of Rails help developers more quickly build a minimum viable product. I'm still able to surprise people who have worked with me for awhile with how quickly I can turn their feature ideas into
    something they can play with and show customers.

  • For continuous integration, like many Rails shops, we use CruiseControl.rb - it's easy to install and customize, but I don't think people are especially enamored of it. But it works. Two very promising alternatives to rolling your own CI server are Devver and RunCodeRun. I've tried both but our app has grown too complex for either of them (we use a lot of gems and have a pretty customized test environment). For Github users, RunCodeRun exposes a post-commit hook so the tests run automatically after every commit which is pretty useful.

  • Speaking of Github, I'd love for them to implement pre-commit hooks, because then you could prevent developers from making commits any time the build is broken, which prevents people from ignoring problems in a large code base and just tunneling on building their one little feature. Right now if you want to implement this, you need to setup your own source control repository that can talk to the continuous integration system.

  • To monitor exceptions, we use the excellent Hoptoad app. This tool adds a lot of context to bug discussions, because nonprogrammers can reference the exact Hoptoad URL containing all of the information a programmer needs to fix a bug (including backtraces). Because it has an RSS feed, one could also use "Unresolved Hoptoad Errors" as a metric influencing the continuous deployment system. If a release goes out and suddenly there are new errors, that's a sign that the batch was bad and needs to be reverted. There's a drop-in Rails plugin but this service could be used with any language.

  • There are two A/B testing plugins for Rails: 7 Minute ABs and A/Bingo. I haven't used either and am not sure there are any better than rolling your own. Update: Charlie Park in the comments mentions the new plugin Vanity which came out just after I wrote this.

  • There are several good unit testing frameworks for Rails, each with their own devotees. What comes with Ruby and Rails is plenty good enough but some people like the greater expressiveness afforded by things like Rspec and Shoulda. For my next product I'd like to try Shoulda because it uses Ruby's built-in test facilities (making for one less dependency to worry about, as is the case with Rspec) and because I really like the examples I've seen on the Thoughtbot blog.

  • We love Cucumber for higher level testing. When coupled with Webrat, which simulates a real browser, you get a pretty nice mechanism for exercising the entire app in a test environment before deployment. Webrat even has a Selenium adapter, so you actually can run your tests inside of a browser to make sure all is well before deploying a change.

  • This isn't Rails-specific, but we use SimpleDB for dumping a lot of important metrics data, like performance measurements, which we then turn into metrics. This keeps us from having to hit our database too much. The RightAWS gem makes interacting with SimpleDB pretty easy.

  • For our metrics we mainly use Graphite, the graphing and analysis system open-sourced last year by Orbitz. Our whole team is falling more in love with it every day.

  • New Relic has a nice plugin for Rails that reports all kinds of useful data to their service, which could become part of a cluster immune system for Rails apps. They measure average responsiveness and compute an aggregate statistic called Apdex which can be a good indicator of site health (at minimum, any significant changes to Apdex should be investigated, and they will email you alerts about such changes).

  • Capistrano is still the standard way most developers are deploying Rails apps (but also check out Vlad the Deployer), but I think there's an opportunity for someone to build a Ruby library to facilitate continuous deployment that would work better than Capistrano. It would definitely be built using Rake like Vlad does.

  • Update: I haven't used Heroku, but as Ryan points out in the comments it definitely belongs on this list as a compelling, get-up-and-running fast deployment platform.

Friday, August 28, 2009

Ruby for Startups Talk at Lone Star Ruby Conference

Today I gave a talk about my experiences writing the code for OtherInbox, called Ruby for Startups. The slides are below. Hope you find them interesting!

The design principals from the first slide come from Russ Olsen's book, Design Patterns in Ruby (and originally from Design Patterns: Elements of Reusable Object-Oriented Software).

Sunday, March 15, 2009

Scaling Rails in the Cloud

Yesterday at SXSW Interactive I gave a talk called "Scaling Rails in the Cloud", about our experiences building OtherInbox using Amazon Web Services. My slides are below. When I wrote this presentation, I really came to the realization that Rails has hardly ever been the problem for us, scaling-wise. The framework has served us very well; all of our problems have stemmed from we the developers not understanding our tools as well as we could have, or not thinking things through. So the actual Rails content is light, but that's because Rails fits right into a cloud environment and we didn't have to do anything special to make it work.

Friday, September 19, 2008

My Rails TakeFive interview

Now that OtherInbox has launched we can publicly talk about what we're doing and why, and what technologies we use and why.  I was honored to be interviewed for the FiveRuns "Take Five" feature. 

Tuesday, August 12, 2008

Humane Sproutcore Server Development Environment

Recently I've started to build a new, rich user interface for OtherInbox using SproutCore, which has been very enjoyable.  One thing that was not enjoyable was properly configuring my development environment.  

In production, you'll usually deploy your SproutCore app as a static file, so all you have to do is arrange for your users to hit that URL (which out of the box is configured as /static, but could be anything).

In development mode, though, you want to be regenerating your client on the fly by serving it dynamically from sc-server.  To use your app, you talk to http://localhost:4020, and if you want your client to communicate with a backend server, you configure the "proxy" setting in sc-config.  Thus when the Sproutcore server gets a request for "/gadgets", it proxies that request to your local development server.

For some kinds of apps, this works well.  For OtherInbox though, everything the Sproutcore app does requires you to be signed-in and have an active session with the Rails application server.  This caused all kinds of cookie problems, probably because of same origin policy (e.g. my Rails app running at otherinbox.dev was issuing cookies that were somehow getting mangled by the proxying process).

Here's what I solved the problem.  Check out my local Apache setup for details about the whole stack:


 <VirtualHost *:80>

ProxyPass /app http://localhost:4020/other_inbox/
ProxyPassReverse /app http://localhost:4020/other_inbox

ProxyPass /static http://localhost:4020/static/
ProxyPassReverse /static http://localhost:4020/static

ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000

ProxyPreserveHost on
</VirtualHost>
See how that works?  When I load http://otherinbox.dev/app in the browser, Apache proxies that request to sc-server, which dynamically generates my Sproutcore client app.  

When components of that app make requests for other parts of Sproutcore, using the /static URL, Apache also proxies those back to sc-server.  

When the app makes requests for anything else, those requests get proxied by Apache to the Mongrel I have running the Rails code.  Because my Sproutcore app is making REST calls to the backend, this ensures that anything the Sproutcore app asks for from my server gets proxied properly, in this case to localhost:3000.

As soon as I did this, all of the cookie issues were done.  You'll also have to add some application-specific code about how you want to force logins if the user is not already signed-in. In our code, I just check for a logged-in cookie, and if it's not there, we open up the URL for a signin window.

Wednesday, July 30, 2008

Cool Medialets Micro-App

My good friend Paul Barry and I have been helping our friends at Medialets out with a neat little Rails micro-app that culls iPhone App Store data from Apple's endless array of plists, and makes a chart, a dynamically-generated Gruff graph, and a bunch of RSS feeds.  

My favorite thing about this app is the New Apps RSS feed which lets me keep up with the newest time-wasters/productivity enhancers for the iPhone.  Let me take this opportunity to say that the world does not need any more iPhone tip calculators or fortune-telling games.

I wrote a bit more about the latest features over at the Medialets blog

Wednesday, July 2, 2008

Contributing to Rails is easier than you think

Rails_2At OtherInbox we love open source and are looking for ways to share some of our labors with the community. Today I came across a great opportunity to contribute something to Ruby-on-Rails core development. I'm posting it here so everyone can see how easy it is to contribute.

I was building a JSON API to enable some new awesome features we're working on. Following the JSON request specification, I had the client setting its MIME type to "application/jsonrequest". But this was not causing Rails to recognize the request as JSON and thus the request body was not properly parsed. After doing some digging, I realized that Rails only looks for MIME type "application/json".

Fortunately, MIME type processing is implemented really humanely in Rails, so I whipped up a little patch that adds "application/jsonrequest" as a synonym for the JSON MIME type. First I wrote a test to prove that this was a problem. Once I had a failing test, I added the MIME type, and got my test passing. I followed the git patch instructions on lighthouse, then jumped into IRC #rails-contrib to garner support for it.

I happened to see that Rick Olson, the author of the existing JSON parsing code, was in the chat, so I pinged him with the lighthouse ticket. He tested it and applied it, and now our one line of code is a part of Rails!

Hopefully this will save some future JSON implementer a bit of pain.

Cross-posted from the OtherInbox blog

Monday, June 2, 2008

RailsConf 2008 Recap

I wrote up a few articles on the OtherInbox blog about my experiences at RailsConf 2008:
The best blow-by-blow coverage so far is from Drew Blas.  Of the ones I attended or heard the best feedback about, I most strongly recommend looking at the slides for these: 

Wednesday, May 28, 2008

See you at Railsconf 2008

I'll be leading two Birds of a Feather sessions at RailsConf 2008 that I hope everyone will attend (or flock to):
I was also invited to sign copies of the book Advanced Rails Recipes (to which I contributed a couple of recipes) at Powell's books in Portland on May 30th at 12:30 pm.  Hope to see you there!

I'll be there with the full OtherInbox contingent, so if you're looking for an awesome startup to join, come and track us down.

Sunday, May 25, 2008

Using Ruby's Autoload Method To Configure Your App Just-in-Time

Reading The Ruby Programming Language was a great experience — like revisiting a country I thought I knew intimately, but with expert tour guides who showed me whole new landscapes. It's also a good primer on what's changing in Ruby 1.9.

One of my favorite discoveries was Ruby's autoload method. Using autoload, you can associate a constant with a filename to be loaded the first time that constant is referenced, like so:
autoload :BCrypt, 'bcrypt'
autoload :Digest, 'digest/sha2'
The first time the interpreter encounters the constant BCrypt, it will load the file 'bcrypt' from Ruby's current load path, which it assumes will contain the definition of that constant. (Note that autoload takes the name of the constant, in symbol form, not the constant itself).

Here's an example of how useful it can be. OtherInbox uses beanstalkd in a few places where we haven't yet migrated to SQS. I was loading the beanstalk client with a Rails initializer, 'config/initializers/beanstalk.rb':
require 'beanstalk-client'
BEANSTALK = Beanstalk::Pool.new(['localhost:11300'])
Making this initial connection on our production server takes five seconds or more each time I restarted the app or dropped into the console. That doesn't sound like much but when you're doing that a few times a day, it starts to add up. So I moved the beanstalk code out of the initializer and into 'lib/etc/load_beanstalk.rb'. I placed all of my autoloads in a single initializer, 'config/initializers/autoload.rb'. For beanstalk, the statement is:
autoload :BEANSTALK, 'etc/load_beanstalk'
Now, the app starts more quickly, and even better, this library doesn't get loaded into memory by parts of the app that don't need it.