How to get SASS to work with Rails 3 on Heroku (without using any plugins)

As a developer, I have realized the need to pay attention in keeping my codes clean as it has a lot of advantages. To ensure this, I believe some of the best choices would be HAML, SASS and COMPASS especially for front-end.

UPDATE: Please note that this post was written for Rails 3.0 way back in 2011. As you can guess, this method has been deprecated. Please follow the official Heroku documentation for the up to date information.

Nowadays, I tend to use SASS full time (with my tiny modular framework) for almost every Rails and Non-Rails project I undertake.

Rails is awesome! When it comes to Rails hosting, I would go for Heroku, as I’m not very keen on debugging ambiguous errors. :-)

I find it a lot more effective in keeping my SASS source files in the app/ directory rather than in a public folder. Basically when the app is up and running, COMPASS dynamically compiles the source file to a .css file and saves it to the stylesheets folder.

So, at first, when I pushed the app to Heroku and tried to access the site, I came across an error page, with the message “We’re sorry, but something went wrong”. When I hit the refresh button again, the site worked fine. I analyzed the log file and I was able to spot the following error log:

1
Errno::EACCES (Permission denied - /app/f284ffb5-1ada-40f4-a401-5ab2cab31922/home/public/stylesheets/compiled/basic.css)

So, we can see that using SASS in Heroku could be a little tricky, because Heroku is a read only system except for the ‘tmp’ folder. This means that we have no way of compiling the codes into the public/stylesheets/compile directory.

Fortunately, we do have a solution for this. What we can do is, compile the source into the ‘tmp’ directory and then link them to the layout files.

You could find some plugins to do this. However, none of them really worked for me, so I fixed it manually, as I am going to show you now.

First of all, you need to change the path of the folder which is going to be used by Compass, to place the compiled .css files, as shown below:

1
2
# File: config/compass.rb
css_dir = "tmp/stylesheets/compiled"

Next, create an initializer file. It doesn’t matter what you name it, but it is encouraged to keep it clear and concise. As for me, I named the file as ‘compass.rb’.

Then, copy the following code to the file:

1
2
3
4
# File: initializer/compass.rb
require 'compass'
require 'compass/app_integration/rails'
Compass::AppIntegration::Rails.initialize!

What this code does is to basically integrate the Compass with Rails when the app is initialized.

Finally we need to tell the Rack middle-ware to set the “tmp” folder as the root folder, when the app requests for the ‘/stylesheets/compile’ folder.

To do this, open the config.ru file and add the following code :

1
2
3
4
# File: config.ru
require ::File.expand_path('../config/environment', __FILE__)
use Rack::Static, :urls => ["/stylesheets/compiled"], :root => "tmp"
run MyApp::Application

That’s all there is to it!
When you are done, push your app to Heroku, restart the server and see what happens.

Rails for Designers

A step-by-step guide to Rails front-end design and development

Be notified when it launches.

We won't send you spam. Unsubscribe at any time.
  • http://twitter.com/sameera207 sameera207

    Hi, Cool stuff, I have already become a fan of HAML, but I’m not that much in to SASS, but anyway great read :D

  • http://kevinelliott.net/ Kevin Elliott

    This works wonderfully, thanks!

  • None

    Why don’t you just use compass dev side, precompile your stylesheets using “compass compile .” and upload the css to Heroku directly…?

    • http://mohamedaslam.com Aslam

      “compass compile” is a not an efficient way to use SASS. If you do that way, you’ll get uncompressed css files with lots of inline comments.

      If you leave it to Rails then, it will compile the SASS file according to the current environment. You’ll only get commented css files in development and compressed css file in production.

      If you still like to compile SASS in production and upload the output files, you can use following command to compress them locally.

      compass compile -e production –force

  • http://twitter.com/akashmanohar Akash Manohar

    A simpler solution. Just add the following line to your production config:

    Compass.configuration.sass_options={:never_update=>true}

    That’s it :) Now when you update the sass files you just have to start the rails dev server once, git commit and push. ka-boom!

  • http://twitter.com/tlchoma Travis Choma

    Thanks for this!

  • http://twitter.com/stouset Stephen Touset

    This will produce failures if you have more than one dyno.

    Web browser makes a request to the page, stylesheets are compiled on that dyno. Web browser makes a request for the stylesheets, hits a separate dyno. Stylesheets don’t exist. Instant FOUC.

  • http://www.tomsquest.com/ Tom

    What about the Heroku documentation on this subject : http://devcenter.heroku.com/articles/using-compass ?

  • Nuwan Chaturanga

    In Rails version > 3 projects with asset pipeline enabled before pushing to heroku I normally run rake assets:precompile which compiles all the css/scss/sass and js/coffee  files to public/app.(minificated and compressed)

    Aslam,

    I am wondering if there any reason to use compass when asset pipeline provides what compass does. 

    • http://mohamedaslam.com Aslam

      Hey Nuwan, glad to see you here. 

      If you noticed closely, I’ve written this blog post when I used version 3.0 which didn’t support asset pipeline.

      Also I think you’ve misunderstood the difference between Compass and SASS. SASS is an extension of CSS and Compass is a CSS Authoring Framework which uses SASS.

      Compass comes with many useful stuffs out of the box. It has CSS grid framework Blueprint built in. So, when you need to use Blueprint, you just need to include a single line of code. “@import blueprint” 

      Another main advantage of using Compass is, we can use “Blueprint” grid system with semantic markup. If you directly use “Blueprint”, you have to use ‘span-*’ classes to specify the grid with. If you use Compass, it provides grid widths as mixins. So, we can give a semantic class for the particular HTML element (eg. div) and use the Compass mixin to specify the width.

      1
      2
      .sidebar
        +column(12)

      Last but not least, if you do front-end design, you know the pain of writing vender prefix for CSS3 styles. For an instance, to get border-radius working in non-CSS3 supported browsers we should write following vender prefixes.

      1
      2
      3
      .sidebar {
        -moz-border-radius: 4px;  -webkit-border-radius: 4px;  -o-border-radius: 4px;  -ms-border-radius: 4px;  -khtml-border-radius: 4px;  border-radius: 4px; 
      }

      But, if you use Compass you can accomplish this by writing a single line mixin.

      1
      2
      .sidebar
         +border-radius(4px)

      Therefore, even Rails 3.1 supports asset pipeline, SASS is not capable of doing those awesome stuffs. :)

      • Nuwan Chaturanga

        Thanks Aslam for the explanation it makes sense now.

        • http://mohamedaslam.com Aslam

          You are welcome! :)