コンテキスト
HerokuでRailsアプリケーションを運用する際は、本番環境とは別にステージング環境を用意することがよくあります。
ステージング環境では通常、Heroku上のRACK_ENV
やRAILS_ENV
といった環境変数をstaging
にします。
これらの環境変数がstaging
になっていると、config/environments/staging.rb
の設定値を読み込んでアプリケーションが起動します。
問題
ただし、assets(CSSやJavaScript等)のprecompile時は必ずしもstaging.rb
が読み込まれるわけではないので注意が必要です。
たとえば、application.css
とは別にawesome.css
をprecompileしたい場合は以下のような指定が必要になります。
config.assets.precompile += %w( awesome.css )
通常こうした設定値はstaging.rb
またはproduction.rb
に設定しますが、heroku_sanやgit push
でステージング環境にソースコードをデプロイするときはstaging.rb
ではなく、production.rb
を読み込んでassets precompileされます。
staging.rb
とproduction.rb
を同時に変更している場合は、あたかもstaging.rb
が読み込まれているように錯覚してしまいますが、先にstaging.rb
だけを更新してHerokuにデプロイしたりすると、awesome.css
がprecompileされないため、以下のようなエラーが発生します。
ActionView::Template::Error (awesome.css isn't precompiled):
ステージング環境のエラーだからstaging.rb
に問題があるのだろうと思い込んでると、永遠に解決しないので要注意です。
対応策
1. production.rbにassets precompile関係の設定を書く
assets precompile関係の設定値が本番環境とステージング環境で変わらないのであれば、常にproduction.rb
に設定値を書いておくという解決策が選択できます。
変わったことをしないのであれば、これが一番手軽かもしれません。
2. デプロイ後に別途assets precompileを実行する
本番環境とステージング環境で設定を変える必要があるなら、コードのデプロイ後にherokuGemを使ってassets precompileを実行しましょう。
こうするとstaging.rb
の設定値を使ってassets precompileしてくれます。
$ heroku run rake assets:precompile --app your-app-staging
3. user_env_compileプラグインを導入する
別途assets precompileを実行するやり方だと、ついassets precompileを忘れてしまう恐れがあります。毎回デプロイと同時に実行する方法はないでしょうか?
user_env_compile
というHerokuのプラグインを導入すると、デプロイ時にstaging.rb
の設定値を使ってassets precompileするようになります。
ただし、このプラグインは実験的なプラグインなので「予告なく削除されるかもしれない」という警告が出ます。
その点に留意した上で使用してください。
備考
ローカル環境でrake assets:precompile
を呼び出した場合もproduction.rb
が読み込まれます。development.rb
ではありません。
もしdevelopment.rb
を使いたいのであれば、下のようにRAILS_ENV
オプションをつけるとdevelopment.rb
を読み込ませることができます。
$ rake assets:precompile RAILS_ENV=development