Set Up A Rails 3.1 App On Heroku Cedar, Ruby 1.9, with Assets Precompiled on the Server
January 7th 2012Someone 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
