Create a gist now

Instantly share code, notes, and snippets.

Configure Carrierwave for Amazon S3 Storage and Heroku
# config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
# Configuration for Amazon S3 should be made available through an Environment variable.
# For local installations, export the env variable through the shell OR
# if using Passenger, set an Apache environment variable.
#
# In Heroku, follow http://devcenter.heroku.com/articles/config-vars
#
# $ heroku config:add S3_KEY=your_s3_access_key S3_SECRET=your_s3_secret S3_REGION=eu-west-1 S3_ASSET_URL=http://assets.example.com/ S3_BUCKET_NAME=s3_bucket/folder
# Configuration for Amazon S3
:provider => 'AWS',
:aws_access_key_id => ENV['S3_KEY'],
:aws_secret_access_key => ENV['S3_SECRET'],
:region => ENV['S3_REGION']
}
# For testing, upload files to local `tmp` folder.
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" # To let CarrierWave work on heroku
config.fog_directory = ENV['S3_BUCKET_NAME']
config.s3_access_policy = :public_read # Generate http:// urls. Defaults to :authenticated_read (https://)
config.fog_host = "#{ENV['S3_ASSET_URL']}/#{ENV['S3_BUCKET_NAME']}"
end
# ...
gem 'carrierwave'
gem 'fog', '~> 1.0.0' # Need to specify version, as carrierwave references older (0.9.0) which doesn't allow configuration of Rackspace UK Auth URL
@avishai
avishai commented Dec 14, 2011

This works great!

@kyleclegg

This is great! I removed config.s3_access_policy and config.fog_host and it's working very well with fog 1.3.1.

@jpmoral
jpmoral commented Aug 11, 2013

Thanks. I needed to rename the initializer to config/initializers/fog.rb to get it to work.

@stevenabrooks

What is the S3_ASSET_URL?

@davity
davity commented Dec 27, 2013

S3_ASSET_URL is the address of the server where you're uploading your files. For example, if you have the next URL for a uploaded file (that you can get from your S3 console at file properties)

https://s3-eu-west-1.amazonaws.com/my_bucket_name/my_awesome_image.png

S3_ASSET_URL="https://s3-eu-west-1.amazonaws.com"
S3_BUCKET_NAME="my_bucket_name"

@shnikola
shnikola commented Jan 3, 2014

config.s3_access_policy= is no longer available. To force http, you can use config.fog_use_ssl_for_aws = false

@heliocola

config.fog_host= doesn't seems to be working.
This link was useful to me: https://github.com/carrierwaveuploader/carrierwave#using-amazon-s3

@nicollecastrog

This gist totally saved me when I was stuck, thank you!!!!!

@grammakov

awesome. It works great. Just don't forget to initialise fog.rb!

@mthees7
mthees7 commented Apr 29, 2014

@grammakov
initialise fog.rb? I'm stuck with some issue that I can't figure out, and I don't have a fog.rb file.

@vrybas
vrybas commented May 4, 2014

The working configuration for me was

# config/initializers/fog.rb

CarrierWave.configure do |config|
  config.fog_credentials = {
    :provider              => 'AWS',
    :aws_access_key_id     => ENV['S3_KEY'],
    :aws_secret_access_key => ENV['S3_SECRET']
  }

  config.fog_directory =  ENV['S3_BUCKET_NAME']
  config.cache_dir     = "#{Rails.root}/tmp/uploads"   # For Heroku
end

config.region is not requried also

@futhr
futhr commented May 21, 2014

And to cleanup your after your specs, you can add this. The wiki example say CarrierWave::Uploader::Base.root but in this case it will wipe your tmp dir with pids and all.

# spec/support/carrierwave.rb

RSpec.configure do |config|

  # config.after(:all, :fog) do
  config.after(:all) do
    FileUtils.rm_rf CarrierWave::Uploader::Base.cache_dir
  end
end
@jackson-sandland

One crucial component...where is the code that goes into the view to facilitate upload? Locally, you can add <% f.file_field :image %> and this creates an upload button that allows you to upload an image. What is the equivalent of that here?

@abatko
abatko commented Jun 24, 2014

@jackson-sandland I believe it is no different than the local approach:

<div class="form-group">
    <%= f.label :avatar %><br>
    <%= f.file_field :avatar, class: 'form-control' %>
    <%#= f.hidden_field :avatar_cache %>
</div>

Also, check out How to: Make Carrierwave work on Heroku and note the fact that making this work on Heroku by setting cache_dir to "#{Rails.root}/tmp/uploads" has the adverse side effect of making uploads not work across form redisplays.

Also, don't use f.hidden_field :avatar_cache as you will occasionally experience undefined method 'to_file' for CarrierWave when hosting on Heroku (due to the fact that each dyno has its own cache directory) - see carrierwaveuploader/carrierwave#725

@mundocalderon

Is this MiniMagick specific? What would be the ImageMagick way of doing this?

  version :print do
    version :thumb    { process :resize_to_fit => [32, 32] }
    version :preview  { process :resize_to_fit => [256, 256] }
    version :full     { process :resize_to_fit => [2048, 2048] }
  end

  version :web do
    version :thumb    { process :resize_to_fit => [32, 32] }
    version :preview  { process :resize_to_fit => [128, 128] }
    version :full     { process :resize_to_fit => [1024, 768] }
  end
@jetaggart

@abatko do you how to get the functionality of :avatar_cache on heroku with multiple dynos?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment