Rails で Paperclip を使って Amazon S3 に画像をアップロードする
画像をアップロードできる機能を、Rails & Paperclip で作ったときに気をつけたところ。 Rails は Heroku で動かして、画像は Amazon S3 に保存するもとのする。
概要
- 基本的には Uploading Files to S3 in Ruby with Paperclip | Heroku Dev Center に従ったら OK
- Gem は最新のものを入れること
- S3 を使う設定をすること
環境
- rails 4.2.4
- paperclip 4.3.1
- aws-sdk 2.2.14
基本的なこと
- Uploading Files to S3 in Ruby with Paperclip | Heroku Dev Center
- GitHub - thoughtbot/paperclip: Easy file attachment management for ActiveRecord
Gem は最新のものを入れる
Gemfile
gem 'paperclip', :git => 'https://github.com/thoughtbot/paperclip.git'
gem 'aws-sdk', '>= 2.0.0'
paperclip 4.3.1 以上では、aws-sdk の 2.0 以上が使えるようになっている。
S3 を使う設定をする
Uploading Files to S3 in Ruby with Paperclip | Heroku Dev Center の “Configuration” の項、 および “International users (additional configuration)” の項を参考に設定する。
config/environments/production.rb
config.paperclip_defaults = {
:storage => :s3,
:bucket => ENV['AMAZON_S3_BUCKET_NAME'],
:s3_region => ENV['AMAZON_S3_REGION'],
:s3_host_name => ENV['AMAZON_S3_HOST_NAME'],
:s3_credentials => {
:access_key_id => ENV['AMAZON_ACCESS_KEY_ID'],
:secret_access_key => ENV['AMAZON_SECRET_ACCESS_KEY']
}
}
設定は環境変数に出しておくと、Production 環境と Staging 環境を分けやすい。
キー | 値 | 例 |
---|---|---|
AMAZON_S3_BUCKET_NAME | バケット名 | my-app-image-bucket |
AMAZON_S3_REGION | リージョン | ap-northeast-1 |
AMAZON_S3_HOST_NAME | S3 のホスト名 | s3-ap-northeast-1.amazonaws.com |
AMAZON_ACCESS_KEY_ID | アクセスキー ID | – |
AMAZON_SECRET_ACCESS_KEY | シークレットアクセスキー | – |
アクセスキー ID およびシークレットアクセスキーは、最低限の権限(AmazonS3FullAccess)を持つユーザーを作成して、そのユーザーの Access Key を使うのが良いと思う。
注意点: リージョンを設定すること
aws-sdk 2.0 以上を使う場合、s3_region
を設定する必要がある。
最新の paperclip を bundle install
したときに、以下のメッセージを標準出力にプリントしてくれるので、スルーしないようにする。
##################################################
# NOTE FOR UPGRADING FROM 4.3.0 OR EARLIER #
##################################################
Paperclip is now compatible with aws-sdk >= 2.0.0.
If you are using S3 storage, aws-sdk >= 2.0.0 requires you to make a few small
changes:
* You must set the `s3_region`
* If you are explicitly setting permissions anywhere, such as in an initializer,
note that the format of the permissions changed from using an underscore to
using a hyphen. For example, `:public_read` needs to be changed to
`public-read`.
Rails 以外で躓いたところ
バケットが非公開になっている
デフォルトではバケットは非公開設定になっているので、画像の URL にアクセスしても Access Denied のエラーが表示される。 解決するためには、以下の方法がある。
- バケットポリシーを作成して、匿名ユーザーへのアクセス許可を付与する
- バケットに作成されたフォルダを
Make Public
する
もちろん、ポリシーを作成する方法の方が良いと思う。ポリシーを作成する方法なら、特定の HTTP Referrer だけにアクセス許可を付与することもできるので。
バケットポリシーの例 - Amazon Simple Storage Service
まとめ・感想
- Paperclip を使って S3 に画像をアップロードできた
- Heroku のドキュメント に丁寧に解説があって分かりやすかった
- Gem が新しくなったので、リージョンを設定する必要があった
- S3 バケットが非公開になっていると、画像を読むことができない
Paperclip のお手軽感が良い。Heroku のマシンイメージに予め ImageMagick が入っているのがお手軽感を増している。