29
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Herokuのスラグサイズを減らすためにasset_syncを使うやりかた

Last updated at Posted at 2013-01-03

Denkinovelという、ノベルゲーム風の小説を書ける投稿サイトをRails + Herokuで開発しています。

サービスの特性上assetsに多くの画像、音楽ファイルを置いているので、HerokuのSlug size 200MB縛りがきつくなってきました。こんな状況のためにasset_syncというgemがあるので、使ってみることにしました。Heroku公式で推奨しているgemです。

herokuでのasset_syncの使い方は、英語公式がこちら。https://devcenter.heroku.com/articles/cdn-asset-host-rails31

ボランティアによる日本語訳もあります。ありがたい。こちらです。https://github.com/herokaijp/devcenter/wiki/cdn-asset-host-rails31

インストール

heroku公式の解説に従って

gem "asset_sync"

をGemfileに書いて

$ bundle

します。
このあとも解説のとおりにherokuの環境変数を設定します。

$ heroku config:add FOG_PROVIDER=AWS
$ heroku config:add AWS_ACCESS_KEY_ID=xxx
$ heroku config:add AWS_SECRET_ACCESS_KEY=yyy
$ heroku config:add FOG_DIRECTORY=yourappname-assets

でherokuの環境変数を追加。
このあと、
config/environments/production.rb内の設定もコメントアウトを外して設定を追加。

config/environments/production.rb
config.action_controller.asset_host = "https://#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"

とします。

asset_syncの設定変更

S3を日本のリージョンで使っている場合は、asset_syncの設定を変える必要があります。

を参考に、

$ rails g asset_sync:install --provider=AWS

します。これで/config/initializer/asset_sync.rb が誕生するので、設定を書き加えましょう。

東京リージョンなので、デフォルトのus-east-1ではなく

/config/initializer/asset_sync.rb
config.fog_region = 'ap-northeast-1'

に修正します。

で推奨されているように、

/config/initializer/asset_sync.rb

では、

/config/initializer/asset_sync.rb
if defined?(AssetSync)
  AssetSync.configure do |config|
    config.fog_provider = 'AWS'
    config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
    config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
    config.fog_directory = ENV['FOG_DIRECTORY']

    # Increase upload performance by configuring your region
    config.fog_region = 'ap-northeast-1'
    #
    # Don't delete files from the store
    # config.existing_remote_files = "keep"
    #
    # Automatically replace files with their equivalent gzip compressed version
    # config.gzip_compression = true
    #
    # Use the Rails generated 'manifest.yml' file to produce the list of files to 
    # upload instead of searching the assets directory.
    # config.manifest = true
    #
    # Fail silently.  Useful for environments such as Heroku
    # config.fail_silently = true
  end
end

というように、

if defined?(AssetSync)
...
end

で囲みます。囲まないでデプロイしたあと、ウェブサイトにアクセスすると**uninitialized constant AssetSync (NameError)**なるエラーが発生しました。注意。

プリコンパイル

asset_syncの設定が完了したら、ローカル環境でプリコンパイルします。assetsのサイズが小さければ、ローカルでのプリコンパイルは必要ないのですが、僕が開発しているDenkinovelの場合、サービスの特性上assetsの容量が大きくならざるをえません。

slug sizeが100MBを越えていたので、プリコンパイルしないでgit push heroku masterするとheroku側でのコンパイルに異様に時間がかかり、time outしてしまいました。なのであらかじめローカルでプリコンパイルしました。

僕はzshを使っているので、.zshenvに

.zshenv
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=yyy
export FOG_DIRECTORY=yourapp-dev-assets

と設定を書き加え、zshを再起動する。

そして

$ rake assets:precompile

すると、ローカルの/public/assets内にassetsが入ると同時にS3にもプリコンパイルされたassetsファイルがアップロードされます。

.slugignoreを作る

assetsはS3にアップロードできました。しかし、まだこのままではslug sizeは減りません。

Heroku公式ドキュメントを参考に、.slugignoreを作りましょう。.slugignoreは名前のとおり、Heroku上でslugを作る際、指定したファイルを無視してslugを構築してくれます。

.slugignore
/spec
/app/assets
*.jpg
*.png
*.mp3
*.ogg

僕は.slugignoreをこう書いて、プロジェクトディレクトリの一番上(.gitignoreがあるのと同じ場所)に置きました。

.slugignore
/spec
/app/assets

だけでいいと思ったんですが、そう書いても.jpgや.mp3を無視してくれませんでした。

デプロイ

.slugignoreができたらとうとうデプロイです。

$ git add . -A
$ git commit -m プリコンパイルした

で変更をcommmitしたら、herokuにpushします。

$ git push heroku master

で、デプロイ完了です。

slug sizeが大幅に小さくなっていることを確認してください。Denkinovelの場合、140MB以上あったのが18MBになりました。

slug size縛りがこうしてなくると、VPSに移行する動機が弱くなってきますね……そのうち移行しようとは思っているのですが、ユーザーが少ないうちはこれで問題なさそうです。

29
28
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?