Today I made a very small change to an app and then deployed it to Heroku. After the deploy was complete I visited the app and was presented with an error page. The error message in the logs let me know that application.css was not compiled, but I couldn’t figure out why. Here’s what I did to break my app, and what I did to track down the issue.
I was installing the heroku_san
gem to make deploying to heroku more of a streamlined process. (I miss the deploy hooks from capistrano, and heroku_san offers a similar mechanism.) I added the heroku_san gem to my :development, :test
group in the Gemfile, and since my project doesn’t use a regular database I needed to alter the deploy strategy. So, I added this to one of my rake files:
require 'heroku_san'
HerokuSan.project = HerokuSan::Project.new(Rails.root.join("config","heroku.yml"), :deploy => HerokuSan::Deploy::Sinatra)
Then I deployed the app, and went to take a look. That’s when I got the error page, and had to start digging.
First I ran heroku logs
to see what was going on. Here’s the bit that stood out.
2013-02-06T03:19:51+00:00 app[web.1]: Completed 500 Internal Server Error in 144ms
2013-02-06T03:19:52+00:00 app[web.1]:
2013-02-06T03:19:52+00:00 app[web.1]: ActionView::Template::Error (application.css isn't precompiled)
Hmmm…. Why would application.css not be precompiled? I took at look at the output from the last deploy, and I couldn’t find any trace of the asset:precompile step having happened. Here’s the last bit of the deploy output:
...
Your bundle is complete! It was installed into ./vendor/bundle
Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Rails plugin injection
Injecting rails_log_stdout
Injecting rails3_serve_static_assets
-----> Discovering process types
Procfile declares types -> web
Default types for Ruby/Rails -> console, rake, worker
-----> Compiled slug size: 18.6MB
-----> Launching... done, v14
There should have been a step for assets:precompile right after the step for writing the database config file.
Wondering if it was a fluke, I made a tiny change and pushed again. Still no dice.
To figure out what was going on I connected directly to a heroku dyno and tried to compile the assets by hand.
$ heroku run bash --app wholesaler-tool-staging
Running `bash` attached to terminal... up, run.xxx
~ $ bundle exec rake assets:precompile
rake aborted!
no such file to load -- heroku_san
Ah-ha! Of course, when any rake task is run, all of the rake tasks have to be loaded. Since heroku_san is not in the gem set for production it can’t be loaded. It would be nice if heroku would surface this error during the deploy instead of allowing it to go past silently.
Anyhoo, I made a quick change to that rake file to wrap the heroku_san stuff in a conditional.
unless Rails.env.production?
require 'heroku_san'
HerokuSan.project = HerokuSan::Project.new(Rails.root.join("config","heroku.yml"), :deploy => HerokuSan::Deploy::Sinatra)
end
I committed the change and deployed again and everything was back to normal.