この記事は
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のいいところ。