事前にprecompileしたassetsをS3に配置してdeployを高速化する方法
Railsで作られているサービスとおもわれるbasecampやgithubはassetsファイルをアプリケーションサーバとは別のCDN(akamaiやCloudFront)サービスから配信している。
CDNに配置する事のメリットとして世界中のEdgeサーバからassetsを配信できるのでどこからアクセスしてもページロードが速い事が一番大きいが、
副次的な効果として事前にassets:precompileすることが可能なためcapistranoでのdeploy時にprecompileしない戦略を取ることによって大幅にdeploy時間を短縮できるメリットがある。
(assetsをgit等ににコミットしてしまってprecompileせずにdeployする戦略もあるがコミットログが汚くなるため避けたい)
今回はasset_syncというgemを使ってS3にassetsを配置しつつcapistranoでdeployする方法を記述します。
このgemはassets:precompileした時に自動的にassetsファイルを指定のストレージに配置してくれる優れものです。
assetsを配置するためのS3のbucketを作成します
今回は下記のbucketを作成します.
Bucket Name: hakutoitoi-assets
GemFileにassset_syncを追加
gem 'asset_sync'
$ bundle install
config/environments/production.rbを編集
# デフォルト以外のパスにassetsを配置したい場合は指定します(デフォルトは/assets) # config.assets.prefix = "/path/to/assets" # 事前に作成しておいたS3のbucketのURLを指定します config.action_controller.asset_host = "//hakutoitoi-assets.s3.amazonaws.com"
assets_syncの設定ファイルを作成する
if defined?(AssetSync) AssetSync.configure do |config| config.fog_provider = 'AWS' config.aws_access_key_id = "XXXXXXXXXXXXX" config.aws_secret_access_key = "XXXXXXXXXXXXX" config.fog_directory = "hakutoitoi-assets" # アップロードするS3エンドポイントを明示的に指定 config.fog_region = 'ap-northeast-1' end end
開発マシンでprecompileする
# precompileすると自動的にS3にassetsがsyncされます $ bundle exec rake assets:precompile RAILS_ENV=production
できあがったassetsからmanifest.ymlだけをコミットする
このファイルがdeployされたソースコードにないとrailsはassetsのパスを解決することができずassetsを利用しているページは500エラーになってしまいます
$ git commit public/assets/manifest.yml $ git push origin master
追記:
Rails3の場合はmanifest.ymlだがRails4からはmanifest-md5hash.jsonが生成されるようになるのでこちらをコミットする必要があるので注意。詳しくはEdge RailsGuideを参照。
http://edgeguides.rubyonrails.org/asset_pipeline.html#precompiling-assets
$ git commit public/assets/manifest-51c7803d58f0eceb1bfb69a398259469.json
Capfileでdeploy/assetsの読み込みをしている場合はコメントアウトする
# こうしないとdeploy時にprecompileしてしまいます # load 'deploy/assets'