Theory of Coding

Web Development blog

Amazons3 + Paperclip

Amazon S3 with PaperClip with Rails

CampusBazaar

I’m currently working on our second project, CampusBazaar, a rails app that allows students to sell their items with their fellow students at their campus. It provides them a way to organize a small shop to sell things that they may not need when moving, or just things in general, such as clothes, mattresses, etc. Upon registration with a .edu email, they are added to their school community. Since pictures are much needed for the item listings, the Paperclip Gem by thoughtbot was used. For installation, just click on the link above.

1
gem 'paperclip'

Why Amazon S3?

When we pushed to Heroku, we realized that the pictures from our database did not stay on the site; it eventually turned into a broken link photo within 5 minutes. It was time to host the pictures externally, because heroku’s dyno restarts, and the image is lost after that. A more stable way is to upload an image directly from the client side and just save the reference url to the database.

  1. You don’t have to use up lots of storage space on your app.
  2. Pulling images from the rails stack every time will make your app super slow.
  3. It will disappear from Heroku anyway
  4. Amazon S3(Simple Storage System) is cheap, it’s free for 12 months, or until 5 GB is used, or 20,000 GET or 2,000 PUT Requests.
  5. After your free tier is over, you can get it for $0.03 per GB for the first 1 TB/month.

Amazon S3

Installation

1
gem 'aws-sdk'

Assuming paperclip was already properly set up, bundle install the ‘aws-sdk’ gem now.

First, get an Amazon S3 account and create a :bucket for your app. You will also need your Amazon Access Key and the Amazon Secret key.

I saved my keys in my application.yml file. This file will not be pushed to github, so don’t worry about people stealing your keys. You must set up the figaro gem to use this feature. Remember to put your key in single quotes ‘ ’, and not double quotes “ ”.

1
2
3
4
# config/application.yml
  amazon_access_key: 'INSERT YOUR KEY HERE'
  amazon_secret: 'INSERT YOUR KEY HERE'
  amazon_bucket_name: 'INSERT YOUR BUCKET NAME HERE'

From then on, I encountered some problems. I searched around google to find out how to set up Amazon S3 with paperclip, and every post seems to have a different answer. There were two posts that were helpful, but did not work for me. It was possible that since my keys were stored in my application.yml file that was not uploaded, it was not able to access my keys. You can try these posts, thoughtbot or devcenter.heroku to see if they work for you. If not, you can follow my tutorial below.

In my config/environments/production.rb, I put the code below. As a reminder, you can get your keys from your application.yml file by using calling ENV[‘whatever you named your key’]. ex. ENV[‘amazon_secret’]

We’re specifying the AWS configuration variables so that we can use it when your app is in production when its up on heroku.

1
2
3
4
5
6
7
8
9
# config/environemnts/production.rb
config.paperclip_defaults = {
  :storage => :s3,
  :s3_credentials => {
    :bucket => ENV['amazon_bucket_name'],
    :access_key_id => ENV['amazon_access_keys'],
    :secret_access_key => ENV['amazon_secret']
  }
}

Then, I put my paperclip config in the development.rb so that I can test it out during development in my localhost:3000

1
2
3
4
5
6
7
8
# config/environments/development.rb
  config.paperclip_defaults = {
  :storage => :s3,
  #:s3_host_name => 'REMOVE_THIS_LINE_IF_YOURE_IN_THE_US',
  :s3_credentials => {
    :bucket => 'YOUR BUCKET NAME'
  }
}

Then, create a aws.yml file in your config directory, if it was not automatically loaded by aws-sdk. You can put different keys in here if you want to

1
2
3
4
5
6
7
8
# config/aws.yml
development:
  access_key_id: ENV['amazon_access_key']
  secret_access_key: ENV['amazon_secret']

production:
  access_key_id: ENV['amazon_access_key']
  secret_access_key: ENV['amazon_secret']

This will be pushed to github, so don’t try to just write your keys here. People will be able to steal your keys. Don’t try to put this in your .gitignore file either, this is essential for the Amazon S3 to work. Just use ENV to grab your keys from your application.yml file.

Lastly, you must add your AWS configuration variables onto heroku in your settings, or you can do it through the command line. Just remember to call the keys the same way you called it in your app. Once you push to heroku master, everything should work.

1
2
3
$ heroku config:set amazon_bucket_name=your_bucket_name
$ heroku config:set amazon_access_key=your_access_key_id
$ heroku config:set amazon_secret=your_secret_access_key

To check whether or not it was successful, on your localhost, do inspect element on your uploaded photo, and see if the url is an amazon url. Then, in production on heroku, also check to see if the url is an amazon url. If it is, then congratulations, you have successfully set up Amazon S3. Happy uploading.