Amazon S3@Tokyo RegionでPaperclipを使う
[追記: 2012/1/19] aws-s3ではなくaws-sdkを使用する仕様に変更されたようなので、ご注意ください。
以前も書きましたが、Ruby on Rails で画像などをアップロードするときにお世話になるGemが「Paperclip」といいます。
結論から先に言うと、Paperclipを修正してAmazon S3@tokyoを使いやすくしたので紹介します。
よって、Paperclipの基本的な使用方法などは説明していませんので、後述のリンクを辿っていただければと思います。
AmazonS3@tokyoを使おうと思ったらエラーがでます
最近、Amazon S3 を使い始めて、東京にもあるということで、「近いほうがいいだろう」という安直な理由で使うことにしたのですが、普通にやろうとするとエラーが続出なんですね。
The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
それで、いろいろ調べてみたのですが、Amazon S3 の東京リージョンに限らず、デフォルト(US)以外のS3を使うのはちょっと面倒らしいのですね。
AmazonS3(Tokyo region) + Paperclip + Rails3を使ってみた
本体に修正が無いあたり、あまり需要がないのかなぁと思っていたけど、そのままだと自分が困るので、私の都合の良いように修正して、pull request 送ったら、紆余曲折ありつつ、無事にマージされたので使い方をさくっと紹介します。
なぜエラーがでるの?
(答え)リージョンによってホスト名が異なるから。
詳細は、こちらで解説されてます。
Amazon S3 の標準はUSなのですが、それ以外を使う場合はホスト名がそれぞれ異なります。
- US Standard * s3.amazonaws.com
- US-West (Northern California) Region s3-us-west-1.amazonaws.com
- EU (Ireland) Region s3-eu-west-1.amazonaws.com
- Asia Pacific (Singapore) Region s3-ap-southeast-1.amazonaws.com
- Asia Pacific (Tokyo) Region s3-ap-northeast-1.amazonaws.com
なので、 :s3_host_name でそれぞれのホスト名を設定します。
:s3_host_name オプションの使い方
:s3_host_name の設定方法は以下の2通り。
- モデルで直接指定する
- config/s3.yml などに設定する
私は後者をオススメします。
なぜなら、開発環境と本番環境でのバケットの変更がスマートに書けます。
直接モデルにも書くことは出来るのですが、ソースが汚くなるので、私は嫌いですね。
config/s3.yml のサンプル
例えば、開発データは東京リージョンに、本番データは別(s3-us-west-1.amazonaws.com)に、という場合、以下のようにする。
# config/s3.yml development: bucket: sample-dev access_key_id: アクセスキー secret_access_key: シークレットキー s3_host_name: s3-ap-northeast-1.amazonaws.com production: bucket: sample-production access_key_id: アクセスキー secret_access_key: シークレットキー s3_host_name: s3-us-west-1.amazonaws.com
参考:AWS セキュリティセンター (AWS Security Center) | アマゾン ウェブ サービス(AWS 日本語)
その場合のモデルはこうなる
# app/models/figure.rb class Figure < ActiveRecord::Base has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :storage => :s3, :s3_credentials => "#{Rails.root}/config/s3.yml", :path => ":attachment/:id/:style/:filename" end
すっきりしましたね。
config/initializers/aws.rb を追加する
[追記:2012/1/19] 現時点において下記のコードは不要です。
残念ながら現状、次のプログラムを追加する必要があります。面倒ですね。今度なんとかしましょう。
#config/initializers/aws.rb AWS::S3::DEFAULT_HOST.replace "s3-ap-northeast-1.amazonaws.com"
参考:PaperclipからAmazon S3のTokyo Regionを使うには。 - このブログは証明できない。
ともあれ、これで以前よりも簡単にS3@tokyoを使えるようになるはずです。
新しいバージョンじゃないと使えません
(追記)既に本体に取り込まれているので、下記の作業は不要です。
2011/7/19の時点で、paperclipは2.3.15ですが、:s3_host_nameオプションは、それには含まれていないので、Gemfileを以下のようにするか、次のバージョンがでるまで待つとよいでしょう。
#Gemfile gem 'paperclip', :git => "git://github.com/thoughtbot/paperclip.git" gem 'aws-s3'