AWS::S3::MissingAccessKey in Paperclip but I've defined both - ruby-on-rails

I'm on Heroku, and this is a portfolio thing which I'm putting up on github for potential employers to look at, so obviously I don't want to stick my keys in a S3.yml file. I've exported S3_KEY and S3_SECRET to my environment both on Heroku and my machine and ruby can access them. But when I try and upload, it gives me the following error:
AWS::S3::MissingAccessKey in Portfolio itemsController#update
You did not provide both required access keys. Please provide the access_key_id and the secret_access_key.
The trace is irrelevant except for my controller line #, which works fine until I try and upload a file. Here's what I have:
class Asset < ActiveRecord::Base
attr_accessible :image, :image_file_name, :image_content_type, :image_file_size, :portfolio_item_id, :order
has_attached_file :image,
:styles => {
:thumb => "100x100#",
:small => "300x300",
:large => "600x600>"
},
:storage => :s3,
:s3_credentials => {
:access_key_id => ENV["S3_KEY"],
:secret_access_key => ENV["S3_SECRET"]
},
:bucket => "bucketybucket",
:path => "portfolio"
end
Anyone know what's going on here? How am I constructing this hash wrong?
Oh, and I've followed this thread, no dice: Paperclip and Amazon S3 Issue

same problem...
seems like that ENV const doesn't load before loading the module. solve by using file argument
like this
:s3_credentials => Rails.root.join('config/amazon_s3.yml')
and in amazon_s3.yml
access_key_id: 'your_key'
secret_access_key: 'your_sec_key'
bucket: 'somebucket'
furthermore, you can set environment variable by using heroku config:add command, which is describe in Heroku DevCenter

The problem is because the Enviroment variable in heroku is different that the enviroment variable in your system, so it may happen that the application works just in one enviroment

Related

AWS::S3::Errors::PermanentRedirect on Heroku

I'm getting following error on heroku after uploading file through paperclip.
AWS::S3::Errors::PermanentRedirect (The bucket you are attempting to
access must be addressed using the specified endpoint. Please send all
future requests to this endpoint.)
This is my settings in the model
has_attached_file :profile_image,
:styles => { :myrecipes => "260x180#"},
:storage => :s3,
:s3_region => 'us-west-1',
:s3_credentials => "#{Rails.root}/config/amazon_s3.yml",
:path => "/images/:id/:style.:extension",
:url => ":s3_domain_url"
This is working on development and store image on S3 but while I'm trying on production (Heroku) I'm getting error.
To Provide the endpoint you have to do add this into your paperclip_defaults
:s3_host_name => "s3-eu-west-1.amazonaws.com"
Or you can do like this
s3_host_name: "s3-#{ENV['AWS_REGION']}.amazonaws.com"
Ref: paperclip issue

Paperclip, S3, Heroku: Missing Image

Long time viewer, first time asker. I've searched for this topic but don't believe I've found the answer.
I have a Post model that has an image. I'm using the Paperclip gem, saving to Amazon S3, and hosting on Heroku.
The file upload form works fine, because I can see that images are sent to my S3 bucket.
The issue is that, the images don't actually show in production.
Here's my model:
class Post < ActiveRecord::Base
attr_accessor :image_file_name, :image_content_type, :image_file_size, :image_updated_at
belongs_to :user
has_many :reviews
has_attached_file :image, styles: { medium: "700x500#", small: "350x250>" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
And here's my config/production.rb:
# Required for Paperclip / AWS
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 here's my show.html.haml file:
.clearfix
.post_image_description
= image_tag #post.image.url(:medium)
.description= simple_format(#post.address)
.description= simple_format(#post.description)
Shouldn't the #post.image.url be enough? What may I be missing to properly route to the image?
This is what I see when I pull Heroku Logs:
2015-06-23T15:38:26.181383+00:00 app[web.1]: ActionController::RoutingError (No route matches [GET] "/images/medium/missing.png"):
For reference, here's my repository for the project: https://github.com/lucasvocos/pitstop
Please let me know if there is anything else to provide in the question, too. As this is my first time asking. Thanks everyone.
I had a similar problem that the upload was working but the display was showing a broken link. I checked the source for the link and it was not pointing to the url shown for the image on S3. I had to add the host name to my paperclip config
config.paperclip_defaults = {
:storage => :s3,
:s3_host_name => 's3-us-west-2.amazonaws.com',
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
You need to set heroku environment variable for s3 bucket variable:
heroku config:set S3_BUCKET_NAME='Your Bucket Name'
heroku config:set AWS_ACCESS_KEY_ID='Your AWS ID'
heroku config:set AWS_SECRET_ACCESS_KEY='Your AWS Secrete Key'
You have to commit the missing.png in \public\images\medium.(make sure \public\images\medium\missing.png exist, then commit). This images is the default until you upload some valid image.
However, also is recommended to define the url in model, something like this:
has_attached_file :image, styles: {
medium: "700x500#",
small: "350x250>" }, :url => '/:class/:attachment/:id/:style_:basename.:extension'

aws-s3 error: AWS::S3::MissingAccessKey error, but keys have been defined?

I'm pretty new to ROR. I've recently deployed an app on heroku and have tried to add an attachment function to the app via paperclip.
I've followed all the steps in adding aws-s3 to my app. Here was my initial code:
user.rb (model)
has_attached_file :avatar,
:styles => {:small => "70x70>"},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style/:basename.:extension"
validates_attachment_size :avatar, :less_than => 1.megabytes
validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/png']
s3.yml (file is located in config folder) note: all of these buckets exist on my aws-s3
development:
bucket: my_avatar-dev
access_key_id: amazonaccesskey
secret_access_key: amazon_secret_access_key
test:
bucket: myapp_avatar-test
access_key_id: amazonaccesskey
secret_access_key: amazon_secret_access_key
production:
bucket: myapp_avatar-pro
access_key_id: amazonaccesskey
secret_access_key: amazon_secret_access_key
gemfile
gem 'aws-s3'
When running this configuration, I would get a error page 500 error when loading my app. Running Heroku logs showed the following error: AWS::S3::MissingAccessKey (You did not provide both required access keys.
So I followed some advice and defined the key and secret_key as environment variables to heroku, using the following line of code:
heroku config:add S3_KEY=amazonaccesskey S3_SECRET=amazon_secret_key
I then added an initializer to test environments and launch via key or .yml file depending on environment, code is as follows:
initializers/s3.rb
if Rails.env == "production"
# set credentials from ENV hash
S3_CREDENTIALS = { :access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET'], :bucket => "myapp_avatar-pro"}
else
# get credentials from YML file
S3_CREDENTIALS = Rails.root.join("config/s3.yml")
end
user.rb model was then update to the following:
has_attached_file :avatar, :storage => :s3, :s3_credentials => S3_CREDENTIALS
I then deployed to heroku and tested the app, but I still keep getting the same error (page 500) and error code: AWS::S3::MissingAccessKey (You did not provide both required access keys.
How is this possible if I have defined the variables in heroku? Is there something I am missing? Is it possible it's something with the gem? Also, I'm using HAML for styling... not sure that matters at all, but just in case it does. I'm quite lost, so any help would be greatly appreciated. Thank you so much!
Having just worked through the same problem and trawling a number of similar posts. I found that any of the possible configurations in the above answer i.e. declaring all of the hashes in the model, using the .yml or using the initializer all work fine from my dev and on heroku as long as the S3 bucket is of US Standard type> The choice is just about how DRY you want to be.
When I originally set S3 up, I used a European bucket. This gave me the spurious error message:
AWS::S3::MissingAccessKey (You did not provide both required access keys.
I note from the AWS site : http://docs.amazonwebservices.com/general/latest/gr/index.html?rande.html
that AWS uses a specific endpoint address for each region to reduce latency and am guessing (because I am a novice coder) that the US standard is either a default or coded into the AWS-S3 plugin. (Maybe someone can edit this up into a more complete answer?)
I solved this problem with this:
:s3_credentials => {
:access_key_id => 'mykey',
:secret_access_key => 'mykey'

paperclip working in development but not working in production?

I'm pretty new to rails and seem to be having an issue with the paperclip gem. I installed the gem and it works well in development (localhost:3000) but when I'm running it on the heroku server, for some reason it does not want to attach files, and the app breaks (error 500 page).
Here is the process i ran... I pushed my file to heroku, heroku ran rake db:migrate (to add paperclip migrations), and then I ran heroku restart (to restart the app with new migrations). This did not seem to help.
Here is the code that I have for paperclip:
user.rb model:
has_attached_file :avatar,
:styles => {:small => "70x70>"},
:url => "/users/:attachment/:id/:style/:basename.:extension",
:path => ":rails_root/public/users/:attachment/:id/:style/:basename.:extension"
validates_attachment_size :avatar, :less_than => 500.kilobytes
validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/png']
edit_form.html.haml view:
= form_for (#user || User.new), :html => { :multipart => true } do |f|
...
.profile_picture.text_field
= image_tag current_profile.avatar.url(:small)
%br
= f.file_field :avatar
Again, for some reason it runs great in development, but breaks down in production. Any pointers would be greatly appreciated... I just cant seem to figure this out and it's pretty frustrating. Thank you so much for your time and any help!
In your model.
has_attached_file :picture,
:styles => {:large => "275x450>"},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => "appname/:attachment/:style/:id.:extension"
In s3.yml in your config dir:
development:
bucket: bucketname
access_key_id: key
secret_access_key: key
production:
bucket: bucketname
access_key_id: key
secret_access_key: key
Then go signup for a bucket at Amazon S3: http://aws.amazon.com/s3/
You could be having a few problems. However, the first is that you can not write to the file system on Heroku. You will have to implement a different storage mechanism such as s3. You can read about this limitation here: http://devcenter.heroku.com/articles/read-only-filesystem

Rails3 - how to get at aws-s3's yml config data in the app?

Specifically, i have a file config/amazon_s3.yml which is used by the aws-s3 gem to set up some s3 config settings like secret keys etc. I also write some of this data into a var in ENV in a different file in initializers so i can reference them in calls to the "has_attached_file" method used by paperclip.
It would be smarter to get the file in initializers to read them out of the s3 config yml, or some config settings for the classes used by the gem, eg something like AWS::S3::Base.connection.secret_access_key (this doesn't work).
Any ideas?
I found the answer here How to use YML values in a config/initalizer
First i load in the yaml in and stick it in a constant.
#config/initializers/constants.rb
S3_CONFIG = YAML.load_file("#{::Rails.root}/config/amazon_s3.yml")
Then, when i set up paperclip for a model, pull in these values, making sure i refer to the current environment:
class Entry < ActiveRecord::Base
has_attached_file :media,
:styles => {
:medium => "300x300>",
:thumb => "110x110>"
},
:storage => :s3,
:bucket =>S3_CONFIG[::Rails.env]["bucket"],
:s3_credentials => {
:access_key_id => S3_CONFIG[::Rails.env]["access_key_id"],
:secret_access_key => S3_CONFIG[::Rails.env]["secret_access_key"]
}
end

Resources