S3 / Paperclip working on Heroku but not Localhost - ruby-on-rails

Paperclip works perfectly for my app on Heroku, but I can't seem to get it working locally. Every time I try to do something I get an "missing required :bucket option" ... but the bucket is there and it works on Heroku!
Here's my model if it helps:
has_attached_file :screen_one, :styles => { :medium => "800x600>", :thumb => "110x80#" },
:storage => :s3,
:s3_credentials => {
:access_key_id => ENV['accesskeyishere'],
:bucket => ENV['sitebuilderreport'],
:secret_access_key => ENV['secretaccesskeyishere']
}
I've changed the access keys since this is a public post :)

I met the same problem (missing :bucket every single where). The answer below works perfectly in my case.
a. Add these to .bash_profile (Note: Fill in with your Amazon account credentials)
export AWS_ACCESS_KEY_ID=XXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXX
export AWS_BUCKET=XXXXXXXXXX
b. This is my development.rb (Note: Copy and paste without changing anything)
Paperclip.options[:command_path] = "/usr/local/bin/"
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['AWS_BUCKET'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
Be sure you rebundle your Rails app with the latest paperclip and aws-s3 gems. Also, make sure you quit your Terminal and run everything again since this is an update to your .bash_profile file.
I hope everything works out now.

You should define the ENV[] variables in your user .bash_profile in mac os.
You should do "heroku config" to see your heroku environement keys for S3 and define it in your local environement.
For example:
$ heroku config
AWS_ACCESS_KEY_ID: your_S3_XXX_key<br />
AWS_SECRET_ACCESS_KEY: your_secret_XXX_key<br />
AWS_BUCKET: your_production_bucket<br />
DATABASE_URL: postgres://xxxxxxx<br />
[...]<br />
You should copy the access_key and secret in your .bash_profile file:
export AWS_ACCESS_KEY_ID=your_S3_XXX_key<br />
export AWS_SECRET_ACCESS_KEY=your_secret_XXX_key
export AWS_BUCKET=your_development_bucket => "Specify new bucket for your dev environement".

In case anyone is doing the same silly thing I did - and making a local script to source that exports all of the AWS environment variables - be sure you source it in the same Terminal session that you're generating the rails server in! If you use split windows (CMD SHIFT D), bear in mind that sourcing the proper environment variables in one does not do so in the other. Very silly mistake but I'm sure (or at least mildly hopeful) that I won't be the only one who makes it.

You can also simply use (filling in the correct values of course):
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => 'AWS_BUCKET',
:access_key_id => 'AWS_ACCESS_KEY_ID',
:secret_access_key => 'AWS_SECRET_ACCESS_KEY'
}
}

I had the same problem and I had config/application.yml (not sure if its a legacy thing or where it came from) but this allows environment variables to be set within rails 'codebase'. I forgot it was here, ignored in heroku and was overriding some settings that were not set.doh!

Related

should i push development.rb and production.rb to heroku

I am able to get apps working on heroku in general - but I recently started using Amazon S3 for images. I can make the process work if I hard code my access keys. But if I set the variables on heroku and then use
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['rails-apps-production'],
:access_key_id => ENV['AWS_ACCESS_KEY'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
in my production.rb file it doesnt work. However, it does work if I use the development.rb code to reference a .yml file with the keys - but I dont want to make that .yml file public and compromise my keys. I know I am doing something wrong. - Should I only be deploying the production.rb file and not the development.rb file? Are they causing conflict? Any guidance is appreciated.
Thanks!

How to set up Amazon S3, paperclip, and ENV variables

I have tried many different ways to set up S3 using ENV variables for image uploads and cannot get it to work. I know my keys and bucket name work, because when I put them straight into the code, my images upload correctly. However, when I try to switch to ENV variables, things do not work.
I used the figaro gem, which created application.yml. In that file, I have:
S3_BUCKET_NAME "xxxxx"
AWS_ACCESS_KEY_ID: "AAAAAAAAA"
AWS_SECRET_ACCESS_KEY: "BBBbbbBBBB"
Not sure if there should be any quotation marks there or not, but right now, I have them in. I have tried without, also.
In my model (listing.rb), I have:
has_attached_file :image,
:styles => { :medium => "200x" , :thumb => "100x100" },
:default_url => "default.png",
:storage => :s3,
:s3_credentials => Proc.new{|a| a.instance.s3_credentials }
def s3_credentials
{:bucket => ENV["S3_BUCKET_NAME"], :access_key_id => ENV["AWS_ACCESS_KEY_ID"],
:secret_access_key => ENV["AWS_SECRET_ACCESS_KEY"]
end
Like I said, when I hard code the values into def s3_credentials, everything works fine. It's just when I try to swap out ENV variables that things fall apart.
In paperclip.rb, I have:
Paperclip::Attachment.default_options[:s3_host_name] = 's3-us-west-2.amazonaws.com'
I also have this code in both production.rb and development.rb:
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
Here is the error message I get when uploading a new image: "The request signature we calculated does not match the signature you provided. Check your key and signing method." On line: "if #listing.save". The ones that were uploaded w/ the credentials hard-coded are still able to be seen in my app.
I'm fairly new to rails and have looked here and other places, including the S3 and paperclip docs, and cannot find a solution that will work. Please let me know if you need to see any other code. I plan on deploying to heroku, if that matters, and saw that figaro is supposed to play nicely with heroku. THANK YOU.
EDIT/UPDATE: For anyone else reading this in the future, Sachin's answer below worked. However, there was a '+' in one of my key IDs. When trying to added the ENV variable via command line, all the characters after the '+' (and including it) were cut off. Simply wrap them in "", and you should be good to go.
Also, I dropped use of the figaro gem, and set up an aws.rb initializer file (per Amazon's instructions). Here are the contents of that file:
AWS.config(
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
)
S3_BUCKET = AWS::S3.new.buckets[ENV['S3_BUCKET']]
And I don't know if this made any difference, but my development.rb and production.rb files now have the following as paperclip defaults:
config.paperclip_defaults = {
:storage => :s3,
:bucket => "your_real_bucket_name_here_in_quotes",
:s3_credentials => {
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
Also note the switch to referring to the ENV bucket name as S3_BUCKET vs. S3_BUCKET_NAME.
And the code in my model (listing.rb) is now this:
has_attached_file :image, :styles => { :medium => "200x", :thumb "100x100"}, :default_url => "default.png", :storage => :s3, :bucket => "your_real_bucket_name_here_in_quotes"
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
You can do one thing:
You can set this configuration in your development.rb or production.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
And If you want to set this environment variables into local then use this:
sudo nano ~/.profile
Then add your variables over here
export S3_BUCKET_NAME="your bucket name"
export AWS_ACCESS_KEY_ID="your access key id"
export AWS_SECRET_ACCESS_KEY="your secret access key"
And then reload your ~/.profile with . ~/.profile
Check added variable with echo $S3_BUCKET_NAME
And for Heroku
You can set your variable like:
heroku config:set S3_BUCKET_NAME="your bucket name"
heroku config:set AWS_ACCESS_KEY_ID="your access key id"
heroku config:set AWS_SECRET_ACCESS_KEY="your secret access key"
Check that variables added or not in heroku with heroku config
For more detail you can refer form here.
Let me know if you need me more..

Paperclip/Rails not reading ENV variables with AWS information

I am trying to use paperclip with S3 AWS. I have set the secret keys and bucket name in the .bash_profile but Rials/Paperclip cannot seem to read them as i get the following error when i try to upload an image in development...
'missing required :bucket option'
If i replace the ENV['S3_BUCKET_NAME'] with the actual name, i then get the following...
'Missing Credentials. Unable to find AWS credentials'
Here is the set-up in the model...
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" },
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
},
:s3_host_name => 's3-eu-west-1.amazonaws.com'
I have tried putting the credentials in the development config file in Rails but i have the same errors. Do i need to tell rails where to look for the ENV variables or am I doing something else wrong here? It seems others are having similar issues but i cannot find a solution.
Thanks for reading.
Just store the AWS bucket, key and key_id in a YAML file and in 'config/initializers', create a new file to read the YAML file contents and set the corresponding ENV variables. Don't forget to restart your rails server
Example
google_client = YAML.load_file("#{Rails.root.join('config/google_client.yml')}")
ENV['GOOGLE_APP_NAME'] = google_client['APP_NAME']
ENV['GOOGLE_CLIENT_ID'] = google_client['CLIENT_ID']
ENV['GOOGLE_CLIENT_SECRET'] = google_client['CLIENT_SECRET']
ENV['GOOGLE_CLIENT_SCOPE'] = google_client['CLIENT_SCOPE']
Typically, we do not push the aws info in Github commit but just ssh to the remote server and place the YAML file in the config folder in our Rails app. So only people who have access to your server can read your aws credentials and not all people even if they have Github access.
tell me if this solves your problem.

What is the proper way to set S3 creds in Rails Development ENV

What is the proper way to set S3 credentials in a Rails development enviroment.
I have
`config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}`
in config/environments/development.rb
but would like to know where to actually set S3_BUCKET_NAME, etc
I recommend the figaro gem. As a bonus it works great with Heroku, too.
I store mine in an external file that gets read in on boot, with a fallback using config/env.rb for defaults. These two gems do the trick for me. The latter adds some nice stuff like whining if an ENV var isn't set that you think should be set.
gem 'dotenv-rails'
gem 'env_bang-rails'

Paperclip/heroku/S3 Configuration is setup as best as I can tell but getting error on upload

Here's the error I get when I try to upload an image through the live site:
ArgumentError (missing required :bucket option):
app/controllers/editions_controller.rb:53:in `block in create'
app/controllers/editions_controller.rb:52:in `create'
I have the latest versions of aws-sdk and paperclip
I've got the following in production.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['bucket_name'],
:access_key_id => ENV['key'],
:secret_access_key => ENV['key2']
}
I've got my AWS_BUCKET set on my heroku app:
AWS_BUCKET: bucket_name
S3_BUCKET_NAME: bucket_name
AWS_ACCESS_KEY_ID: key
AWS_SECRET_ACCESS_KEY: key2
Can anybody suggest why this isn't working? Thanks.
You've got:
:s3_credentials => {
:bucket => ENV['bucket_name']
}
I've always been told that you should capitalize the constants like so:
:s3_credentials => {
:bucket => ENV['BUCKET_NAME']
}
Additionally, you have not actually set an ENV variable called BUCKET_NAME on heroku, you have the following:
AWS_BUCKET: bucket_name
But if your env var is called BUCKET_NAME, then you need the following instead:
BUCKET_NAME: bucket_name
So from the commane line you'd want to run something like heroku config:set BUCKET_NAME=bucket_name
And finally, you've changed the names of your env vars from those that are suggested in the paperclip readme. You've gone with ENV['BUCKET_NAME'] when everyone else uses ENV['AWS_BUCKET']. I dunno if that will effect anything, but try using the process outlined here by heroku.
Try those changes and let me know how they work out. Good luck.

Resources