Rock'n'Hack ブログ

それなりハッカーを目指して、もろもろのメモ。bloggerから引っ越しました。

Railsのassetsをs3に格納し、cloudfrontから配信する


今まで使おう使おうと思いつつ、さほどPVがあるサイトの運営をする機会がなかったため、
やってなかったcloudfrontを満を持して設定してみました。
(とりあえず入れとけ的な話もよく聞きますし…)

今回は、railsのassetsをS3に置いて、cloudfrontから配信するようにしました。
結果、噂通りすごく簡単に導入できたのですが、調査に割りと時間がかかったのでメモしておきます。

Herokuのドキュメントを取っ掛かりにしました。



概要は以下です。

  • assets格納用のS3バケットを作る
  • cloudfrontのdistributionを作成し、S3をorigin serverに設定
  • railsプロジェクトに設定追加
    • Gemfileに、gem "asset_sync" を追加
    • config/initializersに、asset_sync.rb を作成 (カスタム設定の場合)
    • config/environments/production.rbに、asset_host を設定
  • assets:precompile を実施

これだけ、すごく簡単でした。




まずは、S3のバケット作成。 これはcloudfrontを使う方には、特に説明不要と思うので省略。




次に、cloudfrontのdistribution設定。 こちらも、 公式ドキュメントを見ればOKかと思います




で、メインのrailsの設定です。

・Gemfileに、gem "asset_sync"を追加
これはそのままです。bundle install すればOK。


・config/initializersに、asset_sync.rb を作成。
https://github.com/rumblelabs/asset_sync のReadmeを参考に設定。(ymlで設定する例の記載もあります)

まずはrailsコマンドで設定ファイルのテンプレートを作成。
環境変数を使用することで作らなくても使用出来るようですが、個人的に設定ファイルが
あったほうが安心するタイプなので、今回は作りました。

$ rails g asset_sync:install --provider=AWS

下記のような形で自分好みに設定。


・config/environments/production.rbに、asset_host を設定
以下の通り。

  # Enable serving of images, stylesheets, and JavaScripts from an asset server   
config.action_controller.asset_host = "//YOUR_CLOUDFRONT_ENDPOINT"

'//' から始まっているのが変な感じがしますが、こうしておくとアクセスされたプロトコル
(HTTPなら http://YOUR_CLOUDFRONT_ENDPOINTHTTPSなら https://YOUR_CLOUDFRONT_ENDPOINT)
でcloudfrontにもリクエストするとのこと。




asset_syncの準備が出来たので、
bundle exec rake assets:precompile RAILS_ENV=production とかやると…

AssetSync: using config/initializers/asset_sync.rb
AssetSync: Syncing.

Uploading: assets/application-55f294e47fb7ed0b383b882262f9820d.js.gz

Uploading: assets/application-55f294e47fb7ed0b383b882262f9820d.js
AssetSync: Done.

という感じでS3にアップロードされるので、あとはCloudfrontがよしなにキャッシュしてくれます。




最後に、Rails を起動してアクセスすれば、cloudfrontからassetsを取得してることが分かると思います。




以上です。 思ってたよりもすごく簡単に出来ました。

キャッシュというとexpireをどうするか的な問題がもれなくついてくると思いますが、
railsはデフォルトで、ファイル名にハッシュをつけてくれるので問題ないようです。

ハッシュ値自体もファイルの中身から算出するとのことなので、stagingとかproductionとか
いくつか環境があっても共有できます。嬉しい。

また、assets_sync自体も既にS3にあるファイルはアップロードしないので、
余計な時間がかかることもありません。嬉しい。

AWSrails という巨人と、その他素晴らしい先人達の肩にしがみつくと、自分もなんとか生きていける気がしました。


おしまい。

↓参考になります。