この記事は
Railsのproduction環境ではrails assets:precompile
でアセット(imageやjsやcssなど)をコンパイルしておくことになっています。
何も気にせずにrails assets:precompile
をするとpublic
ディレクトリ配下に確かにコンパイルされたアセットが格納されるのですが、puma
でアプリを起動してサイトを開いても反映されていないということがおきます。
それに困った時のメモです。
環境
一応、この記事は以下の環境で試しています。
- ruby 2.6.5
- rails 6.0.2
何が起きているのか
そもそもなんで僕らはassets:precompile
をしているのだろう...
これはRailsガイドさんのサイトがわかりやすいのでそちらを参考に。=>アセットパイプライン - Railsガイド
で、面白いことが書いてあります。
Sprocketsは、production環境では前述のフィンガープリントによるスキームを使用します。デフォルトでは、Railsのアセットはプリコンパイル済みかつ静的なアセットとしてWebサーバーから提供されることが前提になっています。
なんとこれ、Webサーバーから提供されることが前提になっている。
Webサーバーって言うのは代表的なものだとApacheとかNGINXとかそういうやつです。
コンパイルしたファイルをWebサーバー自体に持たせたり、S3などのクラウドストレージに置いておきWebサーバーがそれを参照するように構成されているらしく、
Railsアプリのpublic
ディレクトリを直接参照することはできないようにさせているようです。
で、このpublic
ディレクトリを直接参照することをさせない設定は
# 略
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# 略
に書かれています。コメントアウトを読むと「public
ディレクトリ(フォルダ)から静的なファイルを提供していない」とのこと。
対応
ここまでくれば対応は簡単です。config.public_file_server.enabled
がtrue
になるようにすればいいです。
対応1
単純にconfig/environments/production.rb
を書き換えます。
- config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
+ config.public_file_server.enabled = true
対応2
もう一つの方法として、環境変数RAILS_SERVE_STATIC_FILES
の存在性を検証していることがわかるので、環境変数を設定してあげる方法があります。
私はローカルではDocker Composeで開発をしているので、その場合はこんな感じ。(諸々省略)
services:
rails:
environment:
- RAILS_SERVE_STATIC_FILES=true
もちろんexport
で設定したり、Dockerfile
のENV
に設定したりしてもOK。またtrue
でなくて適当な文字列aaa
とかでもpresent?
がtrue
を返すような物であればなんでもOK。
まとめ
公式(に近い)ドキュメントやコメントアウトを見れば、大体解決できるのがRailsのいいところ。