Matt Van Horn

Things I Like

(and some that I don't)

Pair program with me! (just msg me on twitter, or email mattvanhorn at gmail)

Set Up A Rails 3.1 App On Heroku Cedar, Ruby 1.9, with Assets Precompiled on the Server

January 7th 2012

Someone told me the other day that they had some trouble with this, so here is a quick guide to getting set up on Heroku. This approach is going to compile assets during slug compilation, which I think is the best of the available options.

Step 1

set up a new Rails app

$ rails new placepanda --database=postgresql --skip-test-unit

Step 2

put the app into a Git repo

First, I like to add the following two lines to .gitignore:

config/database.yml
.DS_Store

Heroku makes it own database connection, and I hate those .DS_Store files cluttering up my repository. Now we can get on with the commit.

$ git init
$ git add .
$ git commit -m "my brand new Rails app"

Step 3

Deploy to Heroku as soon as possible. This way we can deal with issues as they arise, not after they accumulate and become hard to track down.

$ heroku create --stack cedar
$ git push heroku master

Now we can look at the app’s status

$ heroku ps

Process  State       Command
-------  ----------  ---------------------------------
web.1    up for 10s  bundle exec rails server -p $PORT

$ heroku logs

2012-01-07T18:35:28+00:00 heroku[api]: Add-on add logging:basic by user@example.com
2012-01-07T18:35:28+00:00 heroku[api]: Release v2 created by user@example.com
2012-01-07T18:36:18+00:00 heroku[slugc]: Slug compilation started
2012-01-07T18:37:08+00:00 heroku[api]: Add-on add shared-database:5mb by user@example.com
2012-01-07T18:37:08+00:00 heroku[api]: Release v3 created by user@example.com
2012-01-07T18:37:08+00:00 heroku[api]: Config add RAILS_ENV, LANG, PATH, RACK_ENV, GEM_PATH by user@example.com
2012-01-07T18:37:08+00:00 heroku[api]: Release v4 created by user@example.com
2012-01-07T18:37:11+00:00 heroku[api]: Deploy cc64c78 by user@example.com
2012-01-07T18:37:11+00:00 heroku[api]: Release v5 created by user@example.com
2012-01-07T18:37:11+00:00 heroku[web.1]: State changed from created to starting
2012-01-07T18:37:15+00:00 heroku[web.1]: Starting process with command `bundle exec rails server -p 40738`
2012-01-07T18:37:18+00:00 heroku[slugc]: Slug compilation finished
2012-01-07T18:37:20+00:00 app[web.1]: [2012-01-07 18:37:20] INFO  WEBrick 1.3.1
2012-01-07T18:37:20+00:00 app[web.1]: [2012-01-07 18:37:20] INFO  ruby 1.9.2 (2011-07-09) [x86_64-linux]
2012-01-07T18:37:20+00:00 app[web.1]: [2012-01-07 18:37:20] INFO  WEBrick::HTTPServer#start: pid=1 port=40738
2012-01-07T18:37:21+00:00 heroku[web.1]: State changed from starting to up

Step 4

I use HAML, so I am installing the haml-rails gem, and so we can check if the assets precompilation on deploy works, I am also building out a minimal app with a HAML view, an image, and a SASS stylesheet. I’ve also installed RSpec, and Thin as the webserver at this point, because that’s just how I roll. You can see the actual commits here

Now I deploy to Heroku again.

$ git push heroku master

And it all seems to be working.

I will update this post a little later, as I add more real-world features to the app, and see if we can’t keep everything working and happy.

Step 5

O.K. – I’m back now, and installing the Compass gem and framework.

$ compass init rails . --syntax sass

edit your Gemfile to include

gem "compass", ">= 0.12.alpha.3"

in the :assets group.

Now, we’ve got to move the sass files to where Rails expects them to be, and also to rename them (to include the ‘.css’) for the assets pipeline.

$ mv app/stylesheets/screen.sass app/assets/stylesheets/screen.css.sass
$ mv app/stylesheets/print.sass app/assets/stylesheets/print.css.sass
$ mv app/stylesheets/ie.sass app/assets/stylesheets/ie.css.sass
$ rm -rf app/stylesheets

Also, we need to update the app/config/application.rb to include:

config.assets.precompile << /^((.*?)\/)?(?!_)[^\/]*$/

(The idea is that this regex prevents the pre-compilation of partials, because if that is attempted, it will fail with errors like “Undefined mixin ‘blueprint-form’”)

I usually put the above line with the regex after the line:

config.assets.enabled = true

Also, in order to use Compass properly, we need to rearrange our stylesheet folder a bit. I make a folder called

app/assets/stylesheets/application

and I put all my custom stylesheets in there.

Then I edit app/assets/stylesheets/application.css, and change from:

*= require_tree .

to:

*= require_tree ./application

This allows the compass stylesheets to render and be included separately, which I prefer. I wind up with one stylesheet for the framework, and one for the rest of my app. My layout head section looks like this:

%head
  %title Placepanda
  = stylesheet_link_tag 'screen.css', :media => 'screen, projection'
  = stylesheet_link_tag 'print.css', :media => 'print'
  /[if IE]
    = stylesheet_link_tag 'ie.css', :media => 'screen, projection'
  = stylesheet_link_tag    "application"
  = javascript_include_tag "application"
  = csrf_meta_tags

Naturally, you might want to do this all in one big file, in which case, I suggest not using the folder structure above, and instead you can just edit the application css to require the files in the right order, as the default alphabetical order is usually non-optimal. It would probably end up like:

*= require_self
* THE COMPASS STYLES
*= require screen
*
* YOUR STYLES THAT NEED TO BE ORDERED
*= require my_stylesheet
*= require my_other_stylesheet
*
* EVERYTHING ELSE IN THE STYLESHEETS FOLDER
*= require_tree .

Now we can deploy to Heroku again

$ git push heroku master

and everything should still be peachy.

Step 6

Installing blueprint.

If you’re following along with the commits on github, at this point, I’ve added my basic app functions, and I just want to style my static pages using blueprint. (The procedure will be similar for other frameworks)

First in my app directory:

$ compass install blueprint

And once again we have to move the files that get created into our assets folder and rename them to ‘some-name.css.sass’

After that, we can just deploy again, and everything is still working.

$ git push heroku master
blog comments powered by Disqus