Super Spread Sheet S³

Or little computing tricks and hacks

Category Archives: AWS

Deploying Rails in Heroku using AWS S3 to store carrierwave files

I am developing an app which requires users to upload pictures on updates. Heroku allows only for transient pictures, staying alive only minutes or seconds in its temporary storage. The solution was to store all the pictures in the cloud.

For this I used AWS. The steps:

  1. Create an account in AWS, which for the first year is free for the first year. The verification process is lengthy and you need a phone as you will receive an automatic call.
  2. Create a bucket, which in Linux terms is a directory. You can do this by going to services -> S3 and there you should have an option for creating a bucket.
  3. Create a IAM user. This is very important to allow you to manage access to your account giving specific permissions. Grab the credentials right then and put them in a safe place. You will not have access to them again, you need to recreate to see them.
  4. To give access privileges to that user, it seems that you have to create a IAM group and grant privileges to that group. Then add the user to the group. There might be a way to just grant access to the user but having a group is the suggested way.
  5. That is all from form the AWS side.
  6. Instead of saving the keys in a file, which you risk adding to the git repository exposing the keys, heroku suggests adding them as environment variables. That is achieved by following the instructions in the link, and breifly it looks like this:

     

    $ heroku config:set S3_KEY=THATVERYLONGSTRING
    Adding config vars and restarting app... done, v12
    S3_KEY: THATVERYLONGSTRING
    
    $ heroku config
    S3_KEY: THATVERYLONGSTRING
    (and any other environment variables that might be set)
    
    $ heroku config:get S3_KEY
    THATVERYLONGSTRING
    
    $ heroku config:unset S3_KEY
    (When you don't need it anymore)
    
  7. If running on development at the same time, do set the environment variables locally as well.
  8. Add the gems to the Gemfile:
    gem 'fog'
    gem 'fog-aws'
  9. I am not sure if both are needed, but I started with fog-aws and was getting errors of initialized variable. Once I added fog, there were no problems. The problem might had been that I am using an older version of carrierwave.
  10. Update the config/initializers/carrierwave.rb and each of the image uploaders. I used the information here and here.

     

    # config/initializers/carrierwave.rb
    
    CarrierWave.configure do |config|
      config.fog_credentials = {
        :provider              => 'AWS',
        :aws_access_key_id     => ENV['S3_KEY'],
        :aws_secret_access_key => ENV['S3_SECRET']
      }
    
      if Rails.env.test? || Rails.env.cucumber?
        config.storage = :file
        config.enable_processing = false
        config.root = "#{Rails.root}/tmp"
      else
        config.storage = :fog
      end
    
      config.cache_dir = "#{Rails.root}/tmp/uploads"
    
      config.fog_directory = ENV['S3_BUCKET_NAME']
    end
    
    #app/uploaders/image_uploader.rb
    
    class ImageAuthorUploader < CarrierWave::Uploader::Base
      storage :fog
      def store_dir
        "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
      end
    end
    
  11. And that should do it! It did for me.

A related post and video presentation on the subject by Nicholas Henry can be found here.