Can carrierwave direct upload to local storage? - ruby-on-rails

Sometimes I am away from internet and still need to work on upload pages. Carrierwave Direct seems to force storage :fog; with no way of overriding in dev.
Is it possible to tell Carrierwave Direct to use local storage (:file) and simply fallback to Carrierwave's development config settings?
Setting storage :file in carrierwave initializer under development config settings doesnt work...carrierwave_direct errors with "is not a recognized provider" from "<%= direct_upload_form_for #uploader do |f| %>".
I have attempted to work around carrierwave direct, but between forcing :fog, expecting a redirect url and expecting the direct_upload_form_for form method...carrierwave_direct is pretty much in charge.
Using storage :file in development would be a welcome feature for the carrierwave_direct gem. Does anyone know how to cleanly do this?

I think it can be done as follows:
CarrierWave.configure do |config|
if Rails.env.development? || Rails.env.test?
config.storage = :file
config.asset_host = ENV["dev_url"]
else
config.fog_provider = 'fog/aws' # required
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: ENV["aws_id"], # required
aws_secret_access_key: ENV["aws_key"], # required
region: ENV["aws_zone"] # optional, defaults to 'us-east-1'
}
config.fog_directory = ENV["aws_bucket"] # required
config.max_file_size = 600.megabytes # defaults to 5.megabytes
config.use_action_status = true
config.fog_public = false # optional, defaults to true
config.fog_attributes = { cache_control: "public, max-age=#{365.day.to_i}" } # optional, defaults to {}
end
end
And in your Uploader add in:
class SomeUploader < CarrierWave::Uploader::Base
if Rails.env.development? || Rails.env.test?
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
end

Related

Fog/Carrierwave config for Rails app on AWS Elastic Beanstalk

I'm trying to set up Carrierwave and Fog to handle image and file uploads on a rails app that I have hosted on AWS' Elastic Beanstalk.
I'm a little confused on how to properly set up the Fog config.
I tried using my AWS Access and Secret keys (commented out in the example below). That through an error on my EB CLI (ERROR: NotAuthorizedError - Operation Denied. The security token included in the request is invalid.)
I'm tyring to use IAM instead of having my Access/Secret codes in my ruby code. Can anyone tell me how to set this up properly?
Here's my config file:
CarrierWave.configure do |config|
# Use local storage if in development or test
if Rails.env.development? || Rails.env.test?
CarrierWave.configure do |config|
config.storage = :file
end
end
# Use AWS storage if in production
if Rails.env.production?
CarrierWave.configure do |config|
config.storage = :fog
end
end
config.fog_credentials = {
:provider => 'AWS', # required
# :aws_access_key_id => 'My Access', # required
# :aws_secret_access_key => 'My Secret', # required
:use_iam_profile => true,
:region => 'eu-west-2' # optional, defaults to 'us-east-1'
}
config.fog_directory = 'elasticbeanstalk-us-west-2-XXXXXXXXXX' # required
#config.fog_host = 'https://assets.example.com' # optional, defaults to nil
config.fog_public = false # optional, defaults to true
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
end
This is a setup that works for me:
config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws' # required
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: ENV['aws_access_key_id'], # required
aws_secret_access_key: ENV['aws_secret_access_key'], # required
#region: 'Singapore', # optional, defaults to 'us-east-1'
#host: 's3.example.com', # optional, defaults to nil
#endpoint: 'olucube-images.s3-website-ap-southeast-1.amazonaws.com', # optional, defaults to nil
}
config.fog_directory = ENV['fog_directory'] # required
#config.fog_public = false # optional, defaults to true
# config.fog_attributes = { 'Cache-Control' => "max-age=#{365.day.to_i}" }, # optional, defaults to {}
end
and I used figaro gem to hold my credentials as follow:
config/application.yml
aws_access_key_id: 'XXXXXXXXXXXXXXXXXXXX'
aws_secret_access_key: 'XXXXXXXXXXXXXXXXXX'
fog_directory: 'myAppName'
This was a bit a of a wild ride. I had a hard time figuring out that Figaro gem. It's probably simple but I didn't really understand it. So for a test, I put my keys directly in the code. It still didn't work.
I pushed my code to github (publicly) and didn't think too much of it. I was going to change the keys just in case. Before I was able to do that someone found my code on github and gained access to my AWS account. They started a bunch of EC2 instances and racked up $3000 worth of usage in a few hours!
My AWS account got suspended and I'm still dealing with having the charges reversed.
Anyway. I found out that you can actually set environment variables on the Elastic Beanstalk web interface. Its under Configuration → Software Configuration. So I did that instead of using Fiagro (much safer IMO). Now it works great. I simplified my Carrierwave config file to only use AWS calling the environment variables from EB. Here's the file:
# config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: ENV['S3_KEY'],
aws_secret_access_key: ENV['S3_SECRET'],
region: ENV['S3_REGION']
}
config.fog_directory = ENV['S3_BUCKET']
config.fog_public = false
config.storage = :fog
end
I changed my uploader files to use fog too. Here's an example:
# app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
Everything works great now. I hope this helps someone else.

Carrierwave + Rails + Cloudfront images returning 500, rails assets is serving

I have this configuration so far....
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: Rails.application.secrets.s3_key, # required
aws_secret_access_key: Rails.application.secrets.s3_secret, # required
region: Rails.application.secrets.s3_region, # optional, defaults to 'us-east-1'
}
# For testing, upload files to local `tmp` folder.
if Rails.env.test? || Rails.env.cucumber? #|| Rails.env.development?
config.storage = :file
config.enable_processing = false
config.root = "#{Rails.root}/tmp"
else
config.storage = :fog
end
config.asset_host = 'http://mycdn.mydomain.com'
config.fog_directory = Rails.application.secrets.s3_bucket
config.fog_public = true
end
http://mycdn.mydomain.com/production/uploads/1/31/dc5d27e2-bd9d-4ba5-8db2-bcbefa52be78.png
# 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
"#{Rails.env}/uploads/#{model.user_id}/#{model.id}"
end
My Rails assets in /assets is working... It's the bucket/directory where Carrierwave is uploading my images that is returning a 500 Error.
Ex: http://mycdn.mydomain.com/production/uploads/3/33/74b1602e-1b9c-4ffd-a53b-bba2323bdb3f.png 500 (Internal Server Error)
Does anyone know what I am missing in my Cloudfront or S3 configuration? Could this be a bucket policy issue? or something else?
Thanks in advance

CarrierWave With Cloudfront Generating wrong URL

Hello I am using Cloudfront with CarrierWave and S3. For some reason in my app I am getting very strange URLs for my cloudfront path when using image_tag and I don't know where I am going wrong. Here is my carrierwave config file
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws' # required
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: 'accesskey', # required
aws_secret_access_key: 'secretaccess key', # required
region: 'us-east-1', # optional, defaults to 'us-east-1'
}
config.fog_directory = 'bwautosales' # required
# config.asset_host = 'randomletters.cloudfront.net'
config.asset_host = 'randomletters.cloudfront.net'
config.fog_public = true
config.fog_attributes = { 'Cache-Control' => "max-age=#{365.day.to_i}" } # optional, defaults to {}
end
and my production.rb file I have
config.action_controller.asset_host = 'randomletters.cloudfront.net'
but in my view when I do something like
<%= link_to image_tag(car.images[0], class: "img-responsive right-block", id: index), car %>
I get this -
src = https://randomletters.cloudfront.net/images/randomletters.cloudfront.net/uploads/car/images/28/car.png"
I'm sure this is an easy fix but don't know where I'm going wrong. Any help would be appreciated!
Image Uploader `
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_whitelist
%w(jpg jpeg gif png)
end
end
`
In your Carrierwave initializer change the line,
config.asset_host = 'randomletters.cloudfront.net' to config.asset_host = 'http://randomletters.cloudfront.net' to get the required cloudfront URL you needed.
You can also remove the line, config.action_controller.asset_host = 'randomletters.cloudfront.net' from Production.rb as the carrierwave itself fetches from the cloud-front url.
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_credentials = {
--------------
--------------
}
config.fog_directory = 'bwautosales'
config.asset_host = 'http://randomletters.cloudfront.net' # please check the change in this line.
config.fog_public = true
config.fog_attributes = { 'Cache-Control' => "max-age=#{365.day.to_i}" } # optional, defaults to {}
end
Just for the sake of adding credibility to Sravan's answer, I had the same problem and when I followed his instructions it started working properly. If you leave out the http:// from
config.asset_host = <>
It gets confused and tries to use a different path with your site's domain name. I had the same issue, but adding http:// to the beginning of the url fixed it.

Rspec and Carrierwave. When changing config.storage to file for testing, I get an ArgumentError is not a recognized storage provider exception

I have two carrierwave uploaders in my application. ImageUploader is for uploading locally and ImageRemoteUploader for uploading to Amazon S3 storage using fog. ImageUploader has storage set to :file and ImageRemoteUploader has storage set to :fog. This setup works fine, but when I start to set up my rspec tests, things change.
The problem arises when I change the ImageRemoteUploader to use :file storage during testing. I do this in my fog initialization file. The file,
/config/initializers/fog.rb, looks like:
CarrierWave.configure do |config|
if Rails.env.test?
config.storage = :file
config.enable_processing = false
else
config.fog_credentials = {
:provider => 'AWS', # required
:aws_access_key_id => 'XXXXXXXX', # required
:aws_secret_access_key => 'XXXXXX', # required
:region => 'XXXX' # optional, defaults to 'us-east-1'
}
config.fog_directory = 'xxx' # required
config.fog_public = true
end
end
When I do this, I get an ArgumentError is not a recognized storage provider carrierwave exception. When I use the fog credentials (I don't set config.storage to :file), the test works as expected.
Carrierwave 0.7.1, Rails 3.2.8, Ruby 1.9.3, Rspec 2.10
Thanks.
I'd try moving the config.storage and config.enable_processing lines into lib/initializers/carrierwave.rb, as recommended in the Carrierwave docs.
Fog also has its own mocking support, which is enabled by running Fog.mock! before the examples. This might be a better approach.

Public URL with Fog and Amazon S3

Versions of all RubyGems. I am using Ruby on Rails 3.1.3, Ruby 1.9.2, CarrierWave 0.5.8, and Fog 1.1.2.
I am using the CarrierWave RubyGem too for image uploading and the Fog RubyGem for Amazon S3 file upload.
In my CarrierWave initializer file I have:
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: 'xxx',
aws_secret_access_key: 'xxx'
}
if Rails.env.production?
config.fog_directory = 'bucket1'
elsif Rails.env.development?
config.fog_directory = 'bucket2'
else
config.fog_directory = 'bucket3'
end
config.fog_public = false
config.fog_authenticated_url_expiration = 60
end
I have an uploader file:
class PageAttachmentUploader < CarrierWave::Uploader::Base
CarrierWave.configure do |config|
if Rails.env.development? || Rails.env.development? || Rails.env.production?
config.fog_public = true
end
end
storage :fog
end
I am having two uploader files. I want one to be set to private and one to public.
I am trying to overwrite CarrierWave configuarations when PageAttachmentUploader is invoked and set the URL to public. This works like charm in the local machine, but it does not work in staging, sandbox and production.
I changed config.fog_public = true in the CarrierWave intializer. Even that does not work in sandbox. How do I fix this problem?
No, you should not use CarrierWave.configure directly in your uploaders as it will change the default configuration for all uploaders and not only each uploader.
I don't know if that's the best solution but you can change the default fog configuration directly by setting class methods in your uploaders like this :
class ImageUploader < CarrierWave::Uploader::Base
storage :fog
def self.fog_public
true # or false
end
end
Actually, the best way (I've found) is to do the following:
class ImageUploader < CarrierWave::Uploader::Base
storage :fog
configure do |c|
c.fog_public = true # or false
end
end
It feels more in line with CarrierWave's style to do it this way.

Resources