Carrierwave AWS Storage

Build Status Code Climate Gem Version Dependency Status

Use the officially supported AWS-SDK library for S3 storage rather than relying on fog. There are several things going for it:

  • Full featured, it supports more of the API than Fog
  • Significantly smaller footprint
  • Fewer dependencies
  • Clear documentation

Here is a simple comparison table [07/17/2013]

Library Disk Space Lines of Code Boot Time Runtime Deps Develop Deps
fog 28.0M 133469 0.693 9 11
aws-sdk 5.4M 90290 0.098 3 8


Add this line to your application's Gemfile:

gem 'carrierwave-aws'


Configure and use it just like you would Fog. The only notable difference is the use of aws_bucket instead of fog_directory, and aws_acl instead of fog_public.

CarrierWave.configure do |config|    = :aws
  config.aws_bucket = ENV.fetch('S3_BUCKET_NAME')
  config.aws_acl    = :public_read
  config.asset_host = ''
  config.aws_authenticated_url_expiration = 60 * 60 * 24 * 365

  config.aws_credentials = {
    access_key_id:     ENV.fetch('AWS_ACCESS_KEY_ID'),
    secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY')

If you want to supply your own AWS configuration, put it inside config.aws_credentials like this:

config.aws_credentials = {
  access_key_id:     ENV['AWS_ACCESS_KEY_ID'],
  secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
  config: AWS.config(my_aws_options)

AWS.config will return AWS::Core::Configuration object which is used through aws-sdk gem. Browse Amazon docs for additional info. For example, if you want to turn off SSL for your asset URLs, you could simply set AWS.config(use_ssl: false).

Custom options for AWS URLs

If you have a custom uploader that specifies additional headers for each URL, please try the following example:

  class MyUploader < Carrierwave::Uploader::Base
    # You can find full list of custom headers in AWS SDK documentation on
    # AWS::S3::S3Object
    def download_url(filename)
      url(response_content_disposition: %Q{attachment; filename="#{filename}"})

If you migrate from fog you probably have something like url(query: {'my-header': 'my-value'}). With carrierwave-aws the query part becomes obsolete, just use a hash of headers.


In order to run the integration specs you will need to configure some environment variables. A sample file is provided as .env.sample. Copy it over and plug in the appropriate values.

cp .env.sample .env
  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request