When using heroku toolbelt, use git remote name instead of app name

Heroku Pipelines is a great feature, letting you more easily maintain multiple environments such as a staging server and production server, for example typing heroku pipeline:promote to push from staging to production more easily (and more quickly) than re-pushing from your local repository up to production. As far as I can tell the heroku command does not document the useful option of being able to use git remote names (instead of heroku app names) when specify which app by using the -r option.

heroku config -r GITREMOTENAME

instead of

heroku config PRODAPPNAME

I find using git remote name useful, easier to remember, and less error-prone because our git remote names in a multiple-app environment are typically consistent and symbolic, such as “stage” and “prod” (as opposed to heroku app names which might or might not bear any relationship to whether they are staging or production, for example “bluebird” and “honeybucket”).

Especially when you are working on several web apps, being able to consistently refer to the ‘staging’ version of the app as ‘stage’ beats the heck out of remembering the specific actual app name (and inadvertently tweaking “bluebonnet” instead of “bluebird”).

Avoid “rate limit” errors when Geocoding in a Heroku app, using QuotaGuard add-on

We added some geocoding to one of our Heroku apps recently, and it seemed to be working fine during development and testing. However, once in production our automatic app health monitoring detected sporatic failures (the worst kind!) in the geocoding process. The logged showed the Google api would suddenly stop returning geocoding results due to rate limiting.

We were aware of Google’s limits on the geocode API, but our app uses geocoding infrequently so we were surprised to see the limits kick in.

In retrospect, the reason was obvious – Google meters usage by IP address, our app is hosted at Heroku, and the zillons of Heroku apps all share a very small number of IP addresses. So even if our usage was trivially small, other Heroku apps were chewing up the geocoding allotment for each Heroku IP.

Fortunately, the folks at www.quotaguard.com offer an add-on (currently in beta) to handle the situation… the ‘test’ plan provides a proxy service good for up to 2500 Google maps API requests/day, so your Heroku app’s requests to the geocoding api come from an IP supplied by Quotaguard (instead of the default Heoku IPs).

Enabling it was a snap:

  1. Add the quotaguard:test addon to your app

heroku addons:add quotaguard:PLAN (quotaguard:test for example)

This will add a QUOTAGUARD_URL setting to your Heroku environment, which you can see via heroku config

  1. If you’re using the geocoder gem, add this to config/initializers/geocoder.rb

Geocoder.configure( :http_proxy => ENV['QUOTAGUARD_URL'].gsub(/^http:\/\//, ''), :timeout => 5 )

Managing multiple Heroku accounts with heroku-accounts plugin

This example assumes your pre-existing heroku account will be heroku.work and you are adding a new account heroku.personal.

It also describes how to move an app from one to the other, for example, if you have hit your 25-app max and are creating a new account and want to move some of your side projects and experimental apps out of your main account.

  1. You probably need to use the plugin to create BOTH your old and your new accounts, eg, if you had one to start with you can’t just add a new heroku.personal, you need to create heroku.work to replace your old one
  2. You’ll need to reassign your old apps to your heroku.work
  3. if you are moving an app, don’t assign the app to heroku.personal (using heroku accounts:set personal) until after you transfer the app using the heroku sharing commmand as described https://devcenter.heroku.com/articles/transferring-apps

So the steps you probably need are:

  1. Install the heroku-account plugin
  2. Go to heroku.com and create your new account (if you don’t have a second account already)
  3. run heroku accounts:add work --auto to create a new heroku.work account to replace your old default account (so use the same credentials you’ve been using all along). You ALSO need to upload your new key to heroku: heroku keys:add ~/.ssh/identity.heroku.work.pub
  4. run heroku accounts:add personal --auto to create a new heroku.personal account (eg use your new credentials for your new heroku account). You ALSO need to upload your new key to heroku: heroku keys:add ~/.ssh/identity.heroku.personal.pub
  5. For each app, cd to the project root then run heroku accounts:set work (all that does it setup git to use your heroku.work, which is (unin this example) the same heroku account you’ve been using all along, only now it’s called heroku.work.
  6. If you want to move an app from heroku.work to heroku.personal,
    (a) add the new heroku account as a collaborator with heroku sharing:add
    (b) in your local directory, switch the app to heroku.personal using heroku accounts:set personal
    (c) transfer** the app from the old account to the new account using heroku sharing:transfer then
    (d) remove the old email address collaborator (if you want to) using heroku sharing:remove

** Note the heroku link I provided says there are special requirements to move an app with any paid resources. Generally, remove the paid resoures, then add them back later, or have support do it.

Quick guide to multiple heroku accounts, and moving apps between them

The heroku-accounts plugin makes it a lot easier to have multiple heroku accounts (work, personal, consulting, etc) on the same machine… this quick how-to guide assumes your pre-existing heroku account will be heroku.work and you are adding a new account heroku.personal.

It also describes how to move an app from one to the other, for example, if you have hit your 25-app max and are creating a new account and want to move some of your side projects and experimental apps out of your main account.

  1. You probably need to use the plugin to create BOTH your old and your new accounts, eg, if you had one to start with you can’t just add a new heroku.personal, you need to create heroku.work to replace your old one
  2. You’ll need to reassign your old apps to your heroku.work
  3. if you are moving an app, don’t assign the app to heroku.personal (using heroku accounts:set personal) until after you transfer the app using the heroku sharing commmand as described https://devcenter.heroku.com/articles/transferring-apps

So the steps you probably need are:

  1. Install the heroku-account plugin
  2. Go to heroku.com and create your new acount (if you don’t have a second acount already)
  3. run heroku accounts:add work --auto to create a new heroku.work account to replace your old default account (so use the same credentials you’ve been using all along). You ALSO need to upload your new key to heroku: heroku keys:add ~/.ssh/identity.heroku.work.pub
  4. run heroku accounts:add personal --auto to create a new heroku.personal account (eg use your new credentials for your new heroku account). You ALSO need to upload your new key to heroku: heroku keys:add ~/.ssh/identity.heroku.personal.pub
  5. For each app, cd to the project root then run heroku accounts:set work (all that does it setup git to use your heroku.work, which is (unin this example) the same heroku account you’ve been using all along, only now it’s called heroku.work.
  6. If you want to move an app from heroku.work to heroku.personal,
    (a) add the new heroku account as a collaborator with heroku sharing:add <strong>new_email</strong>
    (b) in your local directory, switch the app to heroku.personal using heroku accounts:set personal
    (c) transfer** the app from the old account to the new account using heroku sharing:transfer <strong>new_email</strong> then
    (d) remove the old email address collaborator (if you want to) using heroku sharing:remove <strong>old_email</strong>

** Note the heroku link I provided says there are special requirements to move an app with any paid resources. Generally, remove the paid resoures, then add them back later, or have support do it.

Setting the default time zone for a Heroku app

For Rails apps running on Heroku, by default Time.now and some_time.localtime will display in UTC. If you’d like to assign a timezone to your app, you can set the TZ config variable to a time zone (which must be in the tz database timezone format).

Personally I despise the tz database format, because it requires you to guess WHICH city is chosen to represent that time zone (for Pacific, it’s Los_Angeles, not Seattle, not San_Francisco). But that’s what Heroku uses, so to set your app to Pacific you simply run:

heroku config:add TZ="America/Los_Angeles"

The allowed options are listed on the page linked above.

Rails apps can send from multiple SMTP accounts

One of our Rails apps send both bulk email blasts, and also onesey-twosey non-bulk emails such as welcome emails or follow-up emails.

We wanted the non-bulk emails to actually come from one of our monitored customer service accounts, while still using Sendgrid for our bulk email blasts.

When we searched, we found a lot of schemes for configuring Rails to permit multiple SMTP accounts, however they seemed overly complex.

Here’s how we solved it very simply:

  • In addition to our existing user_mailer.rb, we created a new non_bulk_mailer.rb.
  • We removed the ‘normal’ SMTP configuration from environment.rb
  • At the top of each of our xxxx_mailer.rb class definition files we added self.smtp_settings = with the appropriate smtp configuration hash
  • We moved the ‘personal’ email handlers out of the original user_mailer.rb and into non_bulk_mailer.rb (and moved the associated views as well)

So our mailer classes each look like:

class NonBulkMailer < ActionMailer::Base
self.smtp_settings = {
:address => ENV['MF_NONBULK_ADDRESS'],
:port => ENV['NONBULK_PORT'], 
:domain => ENV['NONBULK_DOMAIN'], 
:user_name => ENV['NONBULK_USER'], 
:password => ENV['NONBULK_PWD'] } ...

Note we keep the passwords etc in environment variables, so each environment (local, Heroku staging, Heroku production) can have their own settngs, plus all passwords are kept out of our git repository.

How to migrate from Heroku Shared-database to Dev or Basic Postgres

Heroku recent announced they are nudging out their shared-database offerings, the 5MB (free) and 20GB ($15/mo) plans. For modest app requirements, their new ‘dev’ (free) and ‘basic’ ($9/mo) plans are pretty attractive and seem to offer more reliability, easier management at a comparable price point. The basic plan is brand-new, described here.

For a couple of our apps, I wanted to take the new databases for a spin. I particularly like that they are Postgres 9.1, run on the production infrastructure, and offer a Postgres CLI.

In terms of fun ways to pass time, I’ve always put migrating databases in the same camp as getting a root canal. However, the Heroku folks have made it very easy to migrate – we migrated three databases for three apps in less than 10 minutes.

We migrated our 20GB shared-database apps to the ‘basic’ plan, and actually saved a few bucks per month. Haven’t run benchmarks yet, but our app performance seemed faster on some of the more database-intensive reporting screens.

The steps we took are fairly well documented here by Heroku. (However, the Heroku instructions fail to explain how to get rid of the old shared-database:20gb to prevent continued billing at $15/mo.)

For each app, we cd to the app’s local directory on our dev machine, and use the Heroku CLI to make the following changes. (We ran gem update heroku first to ensure we were using the uptodate CLI.)

First, we installed the postgres add-on:
heroku addons:add heroku-postgresql:basic

When you run the command it created a new database:
Attached as HEROKU_POSTGRESQL_SOMECOLOR
You can see it by typing heroku config

Most of our apps were already running pgbackups:monthly (free), on one of them we ran:
heroku addons:add pgbackups

Put the app in maintenance mode:
heroku maintenance:on

Capture a backup of the current database:
heroku pgbackups:capture --expire
(Took under 2 minutes for a 12 MB database)

Now push that data into the new database:
heroku pgbackups:restore HEROKU_POSTGRESQL_SOMECOLOR

Now make the new database the current database:
heroku pg:promote HEROKU_POSTGRESQL_SOMECOLOR
(Replaces the heroku config variable DATABASE_URL with the URL for the new database. The old shared-database and it’s URL are still there, but they are not the default anymore.)

Check the new database is working:
heroku pg:psql HEROKU_POSTGRESQL_SOMECOLOR
=> select count(*) from users;
(To quit the CLI type \q )

Turn off maintenance mode:
heroku maintenance:off

After you do some testing and make sure everything is fine (it was for us), if you are using the share-database:20gb plan ($15/mo), you’ll want to get rid of that add-on. You cannot, however, remove it, you need to ‘downgrade’ it to the freebie version:
heroku addons:downgrade shared-database
Should display a message the shared-database is downgraded to the free version.

Hmmm, as of August 1st it looks like you CAN remove the shared-database plan…
heroku addons:remove shared-database

Dear Heroku: Quit blaming all of us when you fail. Do this instead…

Dear Heroku,

We developers think you do a good job keeping our apps running smoothly.

But when you have the inevitable outage from time to time, you need to stop telling our customers it’s our fault.

Currently, when I fail (such as a typo in my source code), a visitor to my site sees this:

And currently, when you fail (like this morning), a visitor to my site sees this:

Same message. In other words, when you fail, you’re telling the world it is your customer’s fault.

You apparently assume it has to be this way because many of your platform errors are indistinguishable from actual app errors, so you have no way to differentiate which error message to display.

But that is NOT true.** Here’s your fix. **

AFTER you have confirmed you are having trouble and posted that on your status screen, MANUALLY flip a switch that redirects the default “app error” screen (which you host on AWS) to a different file:

Then once you have things back to normal, flip the switch back to your normal app error message. (Of course, flipping the which-app-error-screen-do-we-show switch doesn’t actually have to be manual, it might happen whenever your internal alarms are triggered. My point is, even if you do it manually it’s really simple and ‘good enuff’.)

The worst case scenario is that apps with an actual app error shows a message suggesting it might not be the app’s fault. But if your underlying platform is unstable, so what?

It’s simple. It’s the right thing to do.

Other than that, keep up the good work.

P.S. Why I love Heroku: To my surprise, this blog post hit the top spot on HN at least briefly. My blog started throwing some app errors. I went to the command line and typed
heroku ps:scale web=10
to throw more dynos at it and was back up. Gotta love that.

Migrating a WordPress blog to Heroku

Moved my blog from Godaddy to Heroku today.

There are several good blog posts about using WordPress + Postgres on Heroku, and in fact I did that at first. However, I could not find any info about *migrating**existing blog* data from Mysql to Postgres.

Since I wanted to migrate my old posts I was pretty sure migrating the WordPress database from MySql to Postgres was likely to introduce some problems. So I used the relatively new Heroku MySql option, ClearDB (which also has a free 5 MB option if that’s large enough for you).

The basic steps were:

  1. using Phpmyadmin on Godaddy, I backed up the database (to SQL format, the default) and downloaded the .sql file to my desktop.
  2. Created a heroku app (cedar stack) mkdir MYBLOGDIR cd MYBLOGDIR git init heroku create MY_BLOG_APP_NAME –stack cedar
  3. Downloaded and extracted the wordpress code wget http://wordpress.org/latest.tar.gz tar xzvf latest.tar.gz; mv wordpress/* . rmdir wordpress
  4. Did a git commit before fidding with settings git add . git commit -am “first checkin” git push heroku master
  5. Added a ClearDb database to the app heroku addons:add cleardb:ignite
  6. Discovered the ClearDB login credentials heroku config

Which displays

CLEARDB_DATABASE_URL => mysql://USER:PASSWORD@HOSTNAME/DBASENAME?reconnect=true
7. Using those credentials, used Sequel Pro (http://www.sequelpro.com/) on my Mac to upload the .sql file to my Heroku database
8. Copied wp-admin-sample.php to wp-admin.php and edited it with the database credentials
9. pushed the revised code back up to Heroku git add . git commit -am “added db credentials” git push heroku master
10. For pre-existing images, I downloaded the wp-content/uploads directory, copied it to my local git repo, the re-pushed to Heroku.
11. For new images, I downloaded the tantan-s3 plugin and installed it per directions… very nicely redirects uploads to my Amazon S3 account. (Of course, you could continue to manually insert images them by adding to a folder in the wp-content/uploads folder, then re-pushing the repo each time, but using S3 is easier.

That’s it, all my old blog posts were there.

I then added my domain name to my heroku app, changed my DNS to point to proxy.heroku.com, and it worked. (I did have to manually reinstall the plugins I was using. Since Heroku does not support unzipping library, you have to download locally, unzip, put in the plugins directory, then do another git push. Not too hard.)

If anyone else will see your git repo, you’d want to use ENV variables for your database password.

I also installed the WordPress SMTP plugin so mail is sent via an SMTP account instead of the php mail() function since that was causing some issues (system emails such as password reminders were not being sent). http://wordpress.org/extend/plugins/wp-mail-smtp/installation/

One more thing, if you are using permalinks…

Since Heroku will not permit the WordPress app to create/re-write the .htaccess file, you need to manually create the following .htaccess file then push to Heroku:

# BEGIN WordPress
 <IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^index\.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
 </IfModule>
 # END WordPress

Getting ActiveAdmin and web-app-themes to work with Rail 3.1 at Heroku

(If all you care about is getting Activeadmin to work at Heroku, skip to step 4. If you want to know how to fix scaffolding to the normal rails default after installing ActiveAdmin, skip to step 7.)

Rails 3.1 at Heroku is not quite an “out of the box” deployment.

Part 1. To get started, I recommend http://blog.bryanbibat.net/2011/09/24/starting-a-professional-rails-3-1-app-with-web-app-theme-devise-and-kaminari/

Part 2. If you used the ‘default’ theme for web-app-theme, you need to add a few styles that all the themes except ‘default’ have. Add the following to the end of app/assets/stylesheets/web-app-theme.css:

/* Write here your css for overriding the theme's rules */<br></br>
.small { font-size:.8em; }<br></br>
.gray { color:#999999; }<br></br>
.hightlight { background-color:#FFFFAA; }<br></br>

Since I’m using rails 3.1 I also had to override the stylesheet to use web fonts. So I moved the /app/assets/web-app-theme/theme/default/fonts folder to /public/fonts and copied the @font-face definitions from the default/style.css to app/assets/stylesheets/web-app-theme.css and simply added a “/” in front of the font paths:

@font-face {
  font-family: "MuseoSans500";
  src: url("/fonts/museosans_500-webfont.eot");
  src: local("☺"), url("/fonts/XXXXX.woff") format("woff"), url("/fonts/XXXX.ttf") format("truetype"), url("/fonts/XXXX-webfont.svg#webfontxx") format("svg");
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "MuseoSans500Italic";
  src: url("/fonts/XXXX.eot");
  src: local("☺"), url("/fonts/XXXX.woff") format("woff"), url("/fonts/XXXX.ttf") format("truetype"), url("/fonts/XXXX.svg#webfontxxf") format("svg");
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "Museo700";
  src: url("/fonts/XXXX.eot");
  src: local("☺"), url("/fonts/XXXX.woff") format("woff"), url("/fonts/XXXXttf") format("truetype"), url("/fonts/XXXX.svg#webfontxx") format("svg");
  font-weight: normal;
  font-style: normal;
}

Part 3. Add ActiveAdmin, per the excellent tutorial at http://net.tutsplus.com/tutorials/ruby/create-beautiful-administration-interfaces-with-active-admin

There is also a very helpful RailsCast for customizing ActiveAdmin at http://railscasts.com/episodes/284-active-admin

Part 4. Add a fix for Devise at https://github.com/plataformatec/devise/commit/96f55a7ac7a61effd03a7f43dbbdfb6af8894579#diff-1 specifically add to config/application.rb
config.assets.initialize_on_precompile = false<br></br>
I also added

  # Enable the asset pipeline<br></br>
  config.assets.enabled = true<br></br>

Part 5. Add a fix for ActiveAdmin at https://github.com/gregbell/active_admin/issues/474, specifically, add this to the top of your routes.rb file:

# The ActiveAdmin routes cause Rails to set up a connection to the
# production database, which isn't available during
# assets:precompile on Heroku, so the following unless block skips
# setting up these routes only when rake assets:precompile is
# being run.<br></br>
#
# Could be a problem if the assets needed these to be loaded to
# compile properly; pretty sure they don't.
break if ARGV.join.include? 'assets:precompile'

Part 6. Heroku was still showing a SASS error after I pushed, which was fixed by moving the sass-rails gen OUT of the assets group (eg, move it amongst the regular gems) in the Gemfile, per http://ygamretuta.me/2011/10/02/setting-up-active-admin-on-heroku-with-rails-3-1-and-cedar/

Part 7. FIXING RAILS SCAFFOLDING. After installing ActiveAdmin, the ‘rails g scaffold’ command no longer works normally. ActiveAdmin adds the inherit_resources gem, which has the side effect of replacing the normal “rails generate scaffold” process to one which by default is based upon inherit_resources. If you want to run the ‘normal’ rails g scaffold command you need to add -c=scaffold_controller at the end of the command line, for example
rails g scaffold Foo name:string -c=scaffold_controller