Skip to content

How to: Make Carrierwave work on Heroku

clyfe edited this page May 27, 2011 · 10 revisions

Heroku has a read-only filesystem, so uploads must be stored on S3 and cannot be cached in the public directory.

You can work around this by setting the cache_dir in your Uploader classes to the tmp directory:

class AvatarUploader < CarrierWave::Uploader::Base
  def cache_dir
    "#{Rails.root}/tmp/uploads"
  end
end

You can also set the cache_dir for all uploaders in an initializer:

CarrierWave.configure do |config|
  config.cache_dir = "#{Rails.root}/tmp/uploads"
end

Note that these techniques will disable the feature of making uploads work across form redisplays. Read the blog post "Using Carrierwave caching on Heroku":http://rickenharp.posterous.com/using-carrierwave-caching-on-heroku and review "this example application":https://github.com/trevorturk/carrierwave-heroku/compare/456b02...master for a technique that attempts to preserve this feature. In brief:

# config.ru
require ::File.expand_path('../config/environment',  __FILE__)
use Rack::Static, :urls => ['/carrierwave'], :root => 'tmp' # adding this line
run YourApplicationName::Application

# config/initializers/carrierwave.rb
CarrierWave.configure do |config|
  config.root = Rails.root.join('tmp') # adding these...
  config.cache_dir = 'carrierwave' # ...two lines

  config.s3_access_key_id = ENV['s3_access_key_id']
  config.s3_secret_access_key = ENV['s3_secret_access_key']
  config.s3_bucket = ENV['s3_bucket']
end

Note that this technique may not work if you have more than one "dyno" on Heroku that has a different "tmp" directory. See the "Heroku documentation":http://docs.heroku.com/constraints#read-only-filesystem for more detail.

Clone this wiki locally