How to get Paperclip and AWS-S3 Singapore (and European) buckets working
Getting the AWS-S3 and Paperclip plugins to work with Singapore (and European) Buckets in S3 is not as straightforward as it seems.
In fact, if you’ve followed most of the guides out there, you’ll probably get an error like:
{% highlight ruby %} The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint {% endhighlight %}
Right now, there’s currently a bug in which non-US bucket URL is not being probably embedded with the aws/s3 plugin and in order to get your Singapore/European buckets to play nice, you’re going to need to make changes to your code.
I hope this guide will be able to save you some time as it has for me.
Step 1: Install aws-s3 and paperclip gem {% highlight ruby %}
Gemfile
gem ‘aws-s3’ gem ‘paperclip’ {% endhighlight %}
Step 2: Get your paperclip models in order.
Step 3: Rewrite your paperclip model to look something like: {% highlight ruby %}
your model
has_attached_file :photo, :storage => :s3, :s3_credentials => “#{RAILS_ROOT}/config/s3.yml”, # if you’re using Rails 3.x, please use #{Rails.root.to_s} instead of #{RAILS_ROOT} :path => “/:style/:id/:filename”, :url => “:s3_sg_url” # if you’re using eu buckets, call it s3_eu_url {% endhighlight %}
Step 4: Create a new file s3.yml in /config and fill in your authentication details. You can edit this file to add different configurations for different buckets.
{% highlight ruby %}
#/config/s3.yml
development:
bucket:
test:
bucket:
production:
bucket:
Step 5: Create a new file /config/initializer/s3.rb {% highlight ruby %}
/config/initializer/s3.rb
if you’re using sg buckets
Paperclip.interpolates(:s3_sg_url) { |attachment, style| “#{attachment.s3_protocol}://s3-ap-southeast-1.amazonaws.com/#{attachment.bucket_name}/#{attachment.path(style).gsub(%r{^/}, “”)}” }
if you’re using eu buckets
Paperclip.interpolates(:s3_eu_url) { |attachment, style| “#{attachment.s3_protocol}://s3-eu-west-1.amazonaws.com/#{attachment.bucket_name}/#{attachment.path(style).gsub(%r{^/}, “”)}” } {% endhighlight %}
Step 6: Update your environments.rb. Add the following {% highlight ruby %}
/config/environments.rb
require ‘aws/s3’ AWS::S3::DEFAULT_HOST = “s3-ap-southeast-1.amazonaws.com” # if using sg buckets
or
AWS::S3::DEFAULT_HOST = “s3-eu-west-1.amazonaws.com” #if using eu buckets.
{% endhighlight %}
And there you have it. Your paperclip should now upload files directly to s3 without any hiccups!
Let me know if you find this guide useful!