私は nginx -> unicorn -> rails の運用サーバーを持っています。アセットをプリコンパイルすると、アセットはファイル名にフィンガープリント (ハッシュ) が追加された状態で public/assets に配置されます。しかし、Web ページが要求されると、application.css および application.js アセットへの参照のフィンガープリントが間違っています。たとえば、rails ヘルパー stylesheet_link_tag は、要求されたフィンガープリントがプリコンパイルされたものと一致しないため、サーバーの public/assets に存在しないファイル名を生成します。画像アセットは正常に動作します (フィンガープリントが一致します)。
これをトラブルシューティングするために、ローカル マシンでアセットをプリコンパイルしたところ、フィンガープリントがサーバー上のプリコンパイルされたフィンガープリントと一致しました。さらに、Webrick をプロダクション モードでローカルに実行すると、すべてが機能します。次に、サーバー上で Webrick を実行してみましたが、うまくいきました。問題の原因は unicorn にあるのではないかと思いました。
私は、--no-default-middleware (または -N) オプションを指定して unicorn を起動することでこの問題を解決しました。これにより、プリコンパイルされたアセットに関して unicorn が期待どおりに動作するようになりました。私の理解では、これは、本来はロードされるはずの Rack ミドルウェアのデフォルト セットをロードしないように unicorn に指示するものです。しかし、なぜこれで問題が解決するのか、そもそも何が間違っているのか、よくわかりません。何が起こっているのでしょうか?
詳細: Ubuntu 12.04、Rails 4.0.1、Ruby 2.1.0、サードパーティのテーマを使用したbootstrap 3.0
アップデート:
これが nginx の問題ではないと思う理由は、ブラウザからページをリクエストしてソースを表示すると、application.css ファイルのファイル名にフィンガープリントがあり、実際には application-3855b1928b94aa5bff5e1dac1aa56882.css のように見えるからです。これは、サーバー上のファイルの実際のフィンガープリントとは一致しません。ローカル開発マシンで同じフィンガープリントを取得しているため、サーバーのフィンガープリントが正しいと確信しています。つまり、クライアントは Web ページをロードし、サーバーに .css ファイルを要求します...nginx はそのリクエストを受け取りますが、.css ファイルは実際には存在しないため見つけることができません。したがって、nginx は期待どおりに動作しています。
フィンガープリントは 2 回生成されます。1 回目はアセットをプリコンパイルするときで、これは正しく動作しています (ほぼ確実)。これは Unicorn の関与なしに行われます。2 回目は、Unicorn ワーカーのコンテキストで Rails が stylesheet_link_tag ヘルパーを確認し、オンザフライでフィンガープリントを計算するときです (これが実行されていると思います)。このとき、何らかの理由で間違ったフィンガープリントが生成されます。まったく同じサーバーで Unicorn を Webrick に置き換えた場合にも同じプロセスが発生しますが、この場合はフィンガープリントが一致します。Unicorn を -N フラグ付きで起動すると、フィンガープリントが一致しますが、これがなぜ違いを生むのか、またなぜ他の誰もこれを行う必要がないのかはわかりません。
答え1
Rails 4では以下の変更を行う必要があります
config.assets.compile = true
config.assets.precompile = ['*.js', '*.css', '*.css.erb']
これは私の場合はうまくいきました。次のコマンドを使用してアセットをプリコンパイルします
RAILS_ENV=production bundle exec rake assets:precompile
からhttps://stackoverflow.com/questions/18700219/rails-4-assets-not-loading-in-production