プリコンパイル済みのアセットを作成する

概要

Rails 3.1で新しいプロジェクトを作ったところ、本番環境でアセットがプリコンパイルされていないというエラーが発生しました。対策として、3.1から導入されたアセットパイプラインのために、プリコンパイル済みのアセットを作成しました。

ActionView::Template::Error (application.css isn't precompiled)



構成

Ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
Rails 3.1.0



問題

Internal Server Errorが発生し、プロダクションログには次のエラーメッセージが出力されていました。

Started GET "/working_records" for 197.8.10.19 at 2011-09-20 11:35:19 +0900
  Processing by WorkingRecordsController#index as */*
Rendered working_records/index.html.erb within layouts/application (0.3ms)
Completed 500 Internal Server Error in 3ms

ActionView::Template::Error (application.css isn't precompiled):
    2: <html>
    3: <head>
    4:   <title>Daylife</title>
    5:   <%= stylesheet_link_tag    "application" %>
    6:   <%= javascript_include_tag "application" %>
    7:   <%= csrf_meta_tags %>
    8: </head>
  app/views/layouts/application.html.erb:5:in `_app_views_layouts_application_html_erb__1440079483388743042_100522000'
  app/controllers/working_records_controller.rb:7:in `index'



解決方法

デフォルトではアセットパイプラインが有効、

FILE: $RAILS_ROOT/config/application.rb

    # Enable the asset pipeline
    config.assets.enabled = true

ライブコンパイルが無効になっています。

FILE: $RAILS_ROOT/config/environments/production.rb

  # Don't fallback to assets pipeline if a precompiled asset is missed
  config.assets.compile = false

この状態だとプリコンパイル済みのアセットを探し、見つからなければエラーになるため、あらかじめプリコンパイル済みのアセットを作成しておく必要があります。別の方法として、ライブコンパイルを有効にし、プリコンパイル済みのアセットが見つからなければ逐次コンパイルする、という方法もあります。


Rakeタスクでプリコンパイル済みのアセットを作成する

Rakeタスクを直接実行し、プリコンパイル済みのアセットを作成する方法です。本番環境で次のコマンドを実行します。

$ bundle exec rake assets:precompile RAILS_ENV=production

$RAILS_ROOT/public/assetsディレクトリにプリコンパイル済みのアセットが作成されます。

$ ls public/assets
application-8af74128f904600e41a6e39241464e03.css
application-8af74128f904600e41a6e39241464e03.css.gz
application-a552e1db33b8be6a42eedf1261916f3c.js
application-a552e1db33b8be6a42eedf1261916f3c.js.gz
jquery-8a50feed8d29566738ad005e19fe1c2d.min.js
jquery-8a50feed8d29566738ad005e19fe1c2d.min.js.gz
jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js
jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js.gz
manifest.yml
rails-bd9ad5a560b5a3a7be0808c5cd76a798.png


cap deployと同時にプリコンパイル済みのアセットを作成する

Capistranoを拡張し、cap deployのプロセスの一環としてプリコンパイル済みのアセットを作成する方法です。Capfileに次の一行を追記します。

FILE: $RAILS_ROOT/Capfile

load 'deploy/assets'

$RAILS_ROOT/public/assetsディレクトリにプリコンパイル済みのアセットが作成されますが、このディレクトリは$RAILS_ROOT/../shared/assetsディレクトリへのシンボリックリンクになっています。


ライブコンパイルを有効にする

設定を変更し、プリコンパイル済みのアセットが見つからなければ逐次コンパイルする方法です。プリコンパイル済みのアセットを作成する必要がない反面、実行中にコンパイルが走るため、パフォーマンス面では多少不利になります。

FILE: $RAILS_ROOT/config/environments/production.rb

  # Don't fallback to assets pipeline if a precompiled asset is missed
  config.assets.compile = true