Alex Liang

Uploading image to AWS S3 with Paperclip

這二天將專案deploy到Heroku,卻因為paperclip和aws-sdk版本問題卡了好久
把解決過程記錄下來,以免未來再踩雷

一開始,照著Heroku 官方教學實作。
沒注意到文章表明此範例不支援aws-sdk 2之後的版本,以及沒指定paperclip的版本,導致圖片上傳失敗

事前準備

1. 必須要有AWS S3的帳號,設定方法可參考[這篇](http://alexliang-blog.logdown.com/posts/385515-aws-uses-s3-for-uploading-images)
2. 己安裝ImageMagick
3. 己安裝Heroku Toolbelt

設定

Gemfile
1
2
gem "paperclip", '~> 4.3.6'
gem 'aws-sdk', '< 2.0'

因為paperclip對新版的aws-sdk尚未支援,aws-sdk採用2.0以前版本;paperclip用穩定版本

config/environments/production.rb
1
2
3
4
5
6
7
8
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}

這裡使用ENV表示機密資訊,你可以在application.yml設定其值(注意此yml檔要加入.gitignore)
但heroku不知道這些值,所以要另外設定

1
2
3
$ heroku config:set S3_BUCKET_NAME=your_bucket_name
$ heroku config:set AWS_ACCESS_KEY_ID=your_access_key_id
$ heroku config:set AWS_SECRET_ACCESS_KEY=your_secret_access_key

新增paperclip.rb檔在config/initializers下

config/initializers/paperclip.rb
1
2
3
4
5
if Rails.env.production?
Paperclip::Attachment.default_options[:url] = your_bucket_url
Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename'
Paperclip::Attachment.default_options[:s3_host_name] = 's3-us-west-1.amazonaws.com'
end

要注意:url的值為’bucket_name’+s3.amazonaws.com,例如bucket取名paperclip-test,則url為paperclip-test.s3.amazonaws.com
而:s3_host_name則需參考AWS文件做相對應的修改。

參考資料:
Stack Overflow討論文章
Paperclip github