1
/
5

assets on S3を導入してみる

こんにちは。エンジニアの志村です。

さて今回ですが、Assets on S3を導入しましたのでその際のメモです。
この形でassetsを配信しているサービスは多いですよね。

今回は、Cloudfront+S3 / asset_sync+capistranoという定番のパターンで実装しております。

assets on S3とは

デプロイ時にassetsファイルをS3に配置し、CDN経由で配信する方法です。
通常であればnginxやApache等のWebサーバーを介して静的ファイルは配信されています。 assets on S3はassetsファイルをS3に配置し、CloudfrontやAkamai等のCDN経由で配信します。Webサーバー負担軽減やCDNを噛ませることによる高速化を目的として用いられることが多いかと思います。

仕組み

1. デプロイ時にrake assets:precompileを走らせる。その際にasset_syncを使用し、S3にassetsファイルをアップロードする。

2. manifestファイルをEC2にアップロードする。

3. rake assets:precompile時に作成されるassetファイルを削除する(public/assetsに格納されている)

こんな感じでしょうか。

他にもCloudfrontやS3の設定があるので、下記に記していきます。


Rails側の設定

ではまずasset_syncを導入し、bundle installをします。

asset_syncの導入

gem 'asset_sync'

次にasset_syncのconfigファイルを生成します。

$ rails g asset_sync:install --provider=AWS

今回はAWSを使用するのでproviderオプションにはAWSを設定します。
そうするとasset_sync.rbという設定ファイルが生成されます。

上記で使用してるIAMに関しては、次の章のS3の部分で説明します。
これでasset_sync自体の設定は完了しました!


assetsのhostをCloudfrontにする

assetsファイルはCloudfrontより配信されます。

通常の設定では、http://domain/assets/配下のファイルが配信されますが、これをhttps://cloudfrontのエンドポイント/assetsに変更し、Cloudfrontから配信するように設定します。

これでassetsファイルがCloudfrontより配信されるようになりました!
次はcapistranoの設定を行います


capistranoの設定

流れとして、

1. cap 〜 deployコマンドを叩いた時に、ローカルにてrake assets:precompileを走らせる(asset_syncが自動的にS3にアップロードしてくれる)

2. manifestファイルをサーバのpublic/assetsディレクトリに転送する

3. ローカルで生成されたpublic/assetsディレクトリを消去する


この中で特に大切なのは2.かと思います。

railsは、productionにデプロイされる際にprecompileを行います。
その際にdigestを付与してファイル名-digest.scssのようなファイル名に変更します。
このdigestはprecompile時にランダムに設定されるのでrails側で管理が必要になります。
そのファイル名を管理するのがmanifestファイルです。これが存在しないと、railsはassetのパスを正しく認識出来ません。

ではcapistranoの設定に移っていきます。
こちらのコードを参考にさせて頂きました。

Capistrano3でasset_syncしてからデプロイする - Qiita
この記事は最終更新日から1年以上が経過しています。 asset_syncをcapistranoでのデプロイ時に実行するようにしました。 asset_syncの実行と実行したあとに出来るmanifestファイルのpushが何とかならないかと思い、capistranoのrun_locallyとuploadを使ってみました。 asset_syncで参考にしたサイト: asset_sync ...
http://qiita.com/rmacchoj7/items/f92568fd8970860f189e


上記のようになります。

rakeタスクに関しては新しくファイルに切り分けても良いかと思いますが、そんなにデプロイスクリプトが多いわけでも無かったので僕はそのままdeploy.rbに書いてしまっています。 release_pathの部分はそれぞれの環境に合わせたpathを指定すればOKです。
developmentではsprocketsを使用しているのでそれをそのままuploadしております。

AWS側の設定

S3の設定

S3はバケットを作成し、CORSの設定を行います。
CORSの設定をしないと、Font Awesomeが正しく表示されません。

詳しくは

[新機能] Amazon CloudFrontがCORSに対応しました | Developers.IO
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。 CloudFrontに大量アップデートがやってきました。このエントリーではCORSに関して解説します。 Amazon CloudFront Adds Device Detection, Geo Targeting, Host Header Forwarding, CORS Support, and more!
http://dev.classmethod.jp/cloud/aws/cloudfront-cross-origin-resource-sharing

を御覧ください。


1. AWSコンソールの「S3」を選択

2. 「バケットの作成」を選択

3. バケット名、リージョンを設定

4. 作成したバケットを選択し、「プロパティ」→「アクセス許可」→「CORS設定の編集」を選択


5. ここに下記のコードを貼り付け、「保存」をします

下記のコードを使用させて頂きました。

S3上にあるファイルがうまく参照できないときのCORS設定 - 直径1.5メートル
Rails でassetsファイルをS3に上げて、そこにある画像を参照しようとすることはよくあると思うのですが、その際にCORSではまったので対応メモ Font-Awesomeを使おうとしてエラー Font-Awesomeを使って表示しているところが、いわゆる豆腐状態(本来フォントが表示されて欲しいところが、□しか表示されない残念な状態)になっていたので開発者ツールのConsoleを確認。 すると、下記のようなエラーが表示されていました。 Font from origin 'https://hoge-bu
http://sora33.hatenadiary.com/entry/2016/06/02/001250
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>


Cloudfrontの設定

● 基本設定

assets用のディストリビューションを作成します。


1. AWSコンソールの「Cloudfront」を選択

2. 「Web」を選択


3. Origin Settingsを入力する


※ Default Cache Behavior Settings, Distribution Settingsに関しては環境に応じて入力して下さい。今回は特にいじらずに行きます。

「Create Distributions」を選択するとCloudfrontのDistributionが作成されます。


● Behaviorの設定

さて、Behaviorの設定を行っていきましょう。
Behaviorは振り分けのルールです。
例えば、

https://xxxx.cloudfront.net/assetsにリクエストが来た場合にはassetsバケットに転送
https://xxxx.cloudfront.net/imagesにリクエストが来た場合にはimagesバケットに転送

のようなことが可能になります。


1. 「Behavior」タブの「Create Behavior」を選択


2. Settingsを入力



「Create」を選択すると、このBehaviorが有効になります。

設定の反映までは10分〜20分ぐらいかかるので気長に待ちましょう!


以上です。

asset_syncのおかげでそこまで多くの手順を踏むこと無く、assets on S3の導入が出来ました。

次回はLambdaを使用してInvalidationを走らせる処理について書きたいと思います。

株式会社クルイト's job postings
8 Likes
8 Likes

Weekly ranking

Show other rankings