A Little Each Day

note to self

Railsでbackground: url();を使って画像が表示されない問題を解決する

こんにちは。本日はRailsの本番環境でassets以下に配置した画像がbackgroundで表示されない問題についてです。

RailsのAsset Pipelineが邪魔をしているようで、このような問題が起きてしまうそうです。

今回はその解決策を共有したいと思います。

起こった問題

サイトのランディングページのbackgroundで表示したい画像をassets/images以下に配置してcss(sass)で読み込んでいました。

.hoge{
  background: url(/assets/images/hoge.jpg);
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}


development環境では問題なく画像を読み込めていて、特にローカル環境ではエラーがありませんでした。


しかし、production環境ではなぜかdevelopment環境で表示されていた画像が表示されないというエラーが発生してしまいました。


原因

本番環境で画像が表示されない理由は、RailsのAssetPipeline(アセットパイプライン)が原因のようです。

キャッシュや表示速度をアップさせるために、Railsは本番環境でデプロイすると、デフォルトでアセットパイプラインが実行されます。

assets/images/以下に置いた画像は、画像のパスにdigestが追加されて、本番環境ではpublic/assets/以下に移動してしまいます。

画像のパスそのものが変わってしまうので、画像自体が読み込めないのは当然といえば当然の結果ですね。。


public/assets以下に画像を置く

アセットパイプラインでassetsからpublicに移動してしまうのなら、前もってpublic以下に置いてしまえばいいのではないかと考えました。

しかし、この方法も弱点があってcapistranoを使っている場合、public/assetsが削除?されてしまうため、こちらの方法も本番環境でエラーが発生してしまいます。


public/images以下に画像を置く

最終的な解決方法としてとったのは、public/imagesディレクトリを作成して、その中に表示させたい画像を置くことにしました。

.jumbotron{
  background: url(/images/hoge.jpg);
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}


これだとcssでbackgroundの画像パスを読み込んでもdigestが追加されることがなく、本番環境でもエラーなく画像を表示できました。



本日は以上です。