I'm trying to setup carrierwave and s3 with heroku. I'm following the carrierwave docs exactly: https://github.com/jnicklas/carrierwave
I've setup a bucket named testbucket in AWS, then I installed fog and created a new initializer with this inside :
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS', # required
:aws_access_key_id => 'my_key_inside_here', # required
:aws_secret_access_key => 'my_secret_access_key_here', # required
:region => 'eu-west-1' # optional, defaults to 'us-east-1'
}
config.fog_directory = 'testbucket' # required
end
Then inside my image_uploader.rb I set
storage :fog
Is there something else I am missing??? Thanks for any help.
If you're using carrier-wave 0.5.2, you have to look in the docs within the gem. They are different than what you see on github. Specifically, check out this file in the gem: lib/carrierwave/storage/s3.rb
Also set store to :s3...not :fog.
You'll see this section:
# CarrierWave.configure do |config|
# config.s3_access_key_id = "xxxxxx"
# config.s3_secret_access_key = "xxxxxx"
# config.s3_bucket = "my_bucket_name"
# end
#
Related
I am struggling with this setup and have read through Carrierwave docs and still and pulling hair.
I'm getting an error when I try to start the server even in dev mode.
Exiting
/Users/my-machine/.rvm/gems/ruby-1.9.3-p327/gems/carrierwave-0.7.1/lib/carrierwave/uploader/configuration.rb:73:in
`eval': can't convert nil into String (TypeError)
Here is my setup.
config/initializers/carrierwave.rb
S3_CONFIG = YAML.load_file(Rails.root.join('config', 'amazon_s3.yml'))[Rails.env]
CarrierWave.configure do |config|
config.storage = :s3
config.s3_access_policy = :public_read
config.s3_access_key_id = S3_CONFIG['access_key_id']
config.s3_secret_access_key = S3_CONFIG['secret_access_key']
config.s3_bucket = S3_CONFIG['bucket']
config.s3_region = 'us-east-1'
end
config/amazon_s3.yml
development:
access_key_id: xxxxxxxxxxxxxxxxxxx
secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bucket: dev-bucket
test:
access_key_id: xxxxxxxxxxxxxxxxxxx
secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bucket: test-bucket
production:
access_key_id: xxxxxxxxxxxxxxxxxxx
secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bucket: prod-bucket
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
# Choose what kind of storage to use for this uploader:
#storage :file
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# fix for Heroku, unfortunately, it disables caching,
# see: https://github.com/jnicklas/carrierwave/wiki/How-to%3A-Make-Carrierwave-work-on-Heroku
def cache_dir
"#{Rails.root}/tmp/uploads"
end
end
How are you establishing your S3_CONFIG environment variables in your development environment? Seems as thou they're missing.
I've been trying to upload files to Amazon S3 through a form, but I'm getting some errors I do not know how to fix.
Does somebody have experience this type of errors?
Heroku log errors:
response => #<Excon::Response:0x00000007294a30 #body="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
Excon::Errors::Forbidden (Expected(200) <=> Actual(403 Forbidden)
config/initializers/carrierwage.rb
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => "AWS",
:aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
config.fog_directory = ENV['AWS_S3_BUCKET']
end
app/uploaders/file_uploader.rb
storage :fog
include CarrierWave::MimeTypes
process :set_content_type
def extension_white_list
%w(jpg jpeg gif png pdf)
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
I have set
the env. variables on Heroku.
I'm using the US standard for the bucket.
I'm trying to get carrierwave working with S3, and I am getting a signature doesn't match error. The weird thing is that it doesn't look like carrierwave is sending the right secret key. In the error, the post is given as:
"Authorization"=>"AWS AKIAIOLWQKSJFH6E3I5Q:vKgyAw2z4c8zzqGWoxLUbw7I5oI="
Which I assume is supposed to be my publickey:privatekey. The thing is that vKgyAw2z4c8zzqGWoxLUbw7I5oI= is not the private key I have stored in fog.rb. Is that right?
Any help is appreciated.
Request/Response:
request => {:chunk_size=>1048576, :connect_timeout=>60, :headers=>{"Content-Length"=>1557, "Content-Type"=>"image/
gif", "x-amz-acl"=>"public-read", "Date"=>"Wed, 24 Oct 2012 12:45:17 +0000", "Authorization"=>"AWS AKIAIOLWQKSJFH6E3
I5Q:vKgyAw2z4c8zzqGWoxLUbw7I5oI=", "Host"=>"s3.amazonaws.com:443"}, :instrumentor_name=>"excon", :mock=>false, :nonb
lock=>true, :read_timeout=>60, :retry_limit=>4, :ssl_ca_file=>"/home/tim/.rvm/gems/ruby-1.9.3-p194/gems/excon-0.16.5
/data/cacert.pem", :ssl_verify_peer=>true, :write_timeout=>60, :host=>"myeasybnb.s3.amazonaws.com", :host_port=>"s3.
amazonaws.com:443", :path=>"/images%2Fb1bb6639-dc08-4981-9a9b-7175093ac970.gif", :port=>"443", :query=>nil, :scheme=
>"https", :body=>#<File:/home/tim/Dropbox/myeasybnb/tmp/uploads/20121024-0845-20225-1170/240x240.gif>, :expects=>200
, :idempotent=>true, :method=>"PUT"}
response => #<Excon::Response:0xa7a1098 #body="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>SignatureD
oesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your
key and signing method.</Message>
fog.rb:
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS', # required
:aws_access_key_id => 'AKIAIOLWQKSJFH6E3I5Q', # required
:aws_secret_access_key => '[my secret key]' # required
}
config.fog_directory = 'myeasybnb' # required
config.fog_public = true # optional, defaults to true
end
Uploader.rb:
# encoding: utf-8
class PhotoUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
# storage :file
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"images"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
class MyUploader < CarrierWave::Uploader::Base
def default_url
asset_path("seeds/" + [version_name, "default.png"].compact.join('_'))
end
end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# Create different versions of your uploaded files:
process :convert => 'jpg'
version :sidecarousel, :if => :is_side_carousel? do
process :resize_to_fit => [2000,1000]
end
version :thumbnail, :if => :is_thumbnail? do
process :resize_to_fill => [240,240]
end
version :linetext, :if => :is_line? do
process :resize_to_fill => [400,200]
end
version :carousel, :if => :is_carousel? do
process :resize_to_fit => [2200, 1000]
end
version :phone do
process :resize_to_fit => [900,900]
end
# def scale(width, height)
# # do something
# end
def is_side_carousel? photo
model.location == 1
end
def is_thumbnail? photo
model.location == 2
end
def is_line? photo
model.location == 3
end
def is_carousel? photo
model.location == 4
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
file.nil? ? #filename = nil : #filename = "#{secure_token}.#{file.extension}"
end
def secure_token
var = :"##{mounted_as}_secure_token"
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end
def cache_dir
"#{Rails.root}/tmp/uploads"
end
end
I managed to fix this. I'm not exactly sure what I did, but there was a couple issues. (1) I think I was getting the auth error because I was specifying a folder in my uploader. Now, I set my directory in the uploader to "" and specify the folder through the fog configuration.
(2) Another error I was getting was a time mismatch. I run mint in a virtual machine for development, and the time was different from reality. Amazon threw an error at that. Once I set the correct time, that went away.
I upgraded an app to Rails 3.2 and installed Bourbon on it. When I make a CSS change locally, for some reason I'm not seeing any change made. Only when I precompile the assets after making a change do I see it in development. Does anyone know what might be going wrong?
Here's my development.rb:
POP::Application.configure do
# Settings specified here will take precedence over those
# in config/application.rb
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
# # GMail settings
# ActionMailer::Base.smtp_settings = {
# :address => "smtp.gmail.com",
# :port => 587,
# :authentication => "plain",
# :enable_starttls_auto => true
# }
end
And application.rb:
require File.expand_path('../boot', __FILE__)
require 'rails/all'
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
module POP
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified
# here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is
# alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector,
# :forum_observer
# Set Time.zone default to the specified zone and make Active Record
# auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names.
# Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from
# config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales',
# '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# Use SQL instead of Active Record's schema dumper when creating the
# database.
# This is necessary if your schema can't be completely dumped by the
# schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Enforce whitelist mode for mass assignment.
# This will create an empty whitelist of attributes available for
# mass-assignment for all models
# in your app. As such, your models will need to explicitly whitelist or
# blacklist accessible
# parameters by using an attr_accessible or attr_protected declaration.
config.active_record.whitelist_attributes = true
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
# Config spec generators
config.generators do |g|
g.test_framework :rspec,
:fixtures => true,
:view_specs => false,
:helper_specs => false,
:routing_specs => false,
:controller_specs => true,
:request_specs => true
g.fixture_replacement :factory_girl, :dir => "spec/factories"
end
config.assets.initialize_on_precompile = false
end
end
Looks like a previous question I hadn't found had the answer. All I needed to do was run:
bundle exec rake assets:clean
I am using the carrierwave gem to manage file uploads in my rails 3 app, however, I am not able to connect to my amazon s3 bucket.
I have followed the instructions on the wiki yet they are not quite detailed enough, for example where do I store my s3 credentials?
Put something like this in an initializer.
CarrierWave.configure do |config|
config.storage = :fog
config.fog_directory = 'your_bucket'
config.fog_credentials = {
:provider => 'AWS',
:aws_access_key_id => 'your_access_key'
:aws_secret_access_key => 'your_secret_key',
:region => 'your_region'
}
end
You can store your credentials right in the file, if you want (and the code is private). Or from a separate file, or the database, up to you. The following would load a config file and allow different configurations based on the env.
# some module in your app
module YourApp::AWS
CONFIG_PATH = File.join(Rails.root, 'config/aws.yml')
def self.config
#_config ||= YAML.load_file(CONFIG_PATH)[Rails.env]
end
end
# config/aws.yml
base: &base
secret_access_key: "your_secret_access_key"
access_key_id: "your_access_key_id"
region: your_region
development:
<<: *base
bucket_name: your_dev_bucket
production:
<<: *base
bucket_name: your_production_bucket
# back in the initializer
config.fog_directory = YourApp::AWS.config['bucket_name']
# ...
config.fog_credentials = {
:provider => 'AWS',
:aws_access_key_id => YourApp::AWS.config['access_key_id'],
:aws_secret_access_key => YourApp::AWS.config['secret_access_key'],
:region => YourApp::AWS.config['region']
}
Check out this quick blog post I wrote about how to do it. Basically there are a few steps, each of which is pretty complicated:
Configuring API keys (allowing you to connect to the Amazon S3 API)
Connecting the API keys to your account (make sure to keep the credentials not checked into GitHub if you're using a public repo though)
Deploying the changes out.
Hope this helps!