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: -dev access_key_id: <aws_access_key_id> secret_access_key: <aws_secret_access_key>

test: bucket: -test access_key_id: <aws_access_key_id> secret_access_key: <aws_secret_access_key>

production: bucket: -production access_key_id: <aws_access_key_id> secret_access_key: <aws_secret_access_key> {% endhighlight %}

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!