Resources
- Heroku Dev Center article on Paperclip and S3
- Paperclip gem docs
- Paperclip S3 Storage module docs
- StackOverflow post on path and url configuration for Paperclip and S3
- dotenv gem docs
- AWS access key management instructions
- finding AWS API keys
- Install
imagemagick
on your computer.
$ brew install imagemagick
- Add paperclip to your Gemfile.
gem 'paperclip'
- Add paperclip code to your
User
model.
class User < ActiveRecord::Base
has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/
end
The :styles
attribute creates various styles of images, which will be accessible later with paperclip url helpers:
<%= image_tag @user.avatar.url %>
<%= image_tag @user.avatar.url(:medium) %>
<%= image_tag @user.avatar.url(:thumb) %>
- Create a migration
$ rails g paperclip user avatar
class AddAttachmentAvatarToUsers < ActiveRecord::Migration
def up
add_attachment :users, :avatar
end
def down
remove_attachment :users, :avatar
end
end
-
rake db:migrate
-
Add a file field to your
users#new
form.
<%= f.file_field :avatar %>
Remember to add :avatar
to user_params
This solution works locally, but in order to save images in the cloud you'll need to set up an Amazon S3 bucket. S3 will require some secret keys, so you'll also set up a way to use environment variables to store those secret keys.
Never EVER check a secret key into git
If your key has already been checked in, even if you didn't push; go and revoke that key immediately. Hackers can easily scan even OLD commits for keys in minutes.
HACKERS CAN CHARGE THOUSANDS OF DOLLARS TO YOUR AMAZON WEB SERVICES ACCOUNT IN JUST A FEW DAYS!
Carefully follow the instructions in our how to hide secret keys guide.
-
You will use a
.env
file to store secret environment varaibles. Immediately, BEFORE YOU CREATE ANY NEW FILES, add a line that says.env
to your.gitignore
, then add and commit this.gitignore
change. -
For environment variables, add the dotenv gem to your
Gemfile
before paperclip. Then add a.env
file to the root directory of your project. -
Sign into an Amazon Web Services (AWS) account and select S3. Create a new bucket. Generate a new API key, and copy both the API key id and the secret key into the
.env
file. PROTECT THIS API KEY -- DO NOT COMMIT TO GITHUB!!
- Add your
AWS_BUCKET
, AWS_PUBLIC_KEY, and AWS_SECRET your secrets file - this will be the.env
file if you are using thedotenv
gem or thesecrets.sh
file if you are manually managing your secret keys.
S3_BUCKET_NAME="your bucket name here"
AWS_ACCESS_KEY_ID="super secret shhhhh"
AWS_SECRET_ACCESS_KEY="do not push me to github"
Remember to add your secret key file to your
.gitignore
! Seriously.
- Add the
aws-sdk
gem to yourGemfile
. Don't forget to bundle.
gem 'aws-sdk'
- In your
config/environments/development.rb
andconfig/environments/production.rb
, add the following configuration for paperclip:
# Configure paperclip for uploading photos to AWS S3 bucket
config.paperclip_defaults = {
:storage => :s3,
:bucket => ENV['S3_BUCKET_NAME'],
:url => ":s3_domain_url",
:path => "/:class/:attachment/:id_partition/:style/:filename",
:s3_credentials => {
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
s3_region: nil
}
}
-
Now it should work locally! Upload a file to see it added to your bucket.
-
Push your changes to GitHub, and check your repository on GitHub. Make sure your secrets file is not in the repository.
-
If your secret key file was accidentally checked into GitHub, FOLLOW THESE STEPS IMMEDIATELY:
- Deactivate and delete the current AWS keys according to Amazon's instructions.
- Remove the secrets file from your GitHub tracking:
git rm .env
orgit rm secrets.sh
. - Do a git commit to delete the file from git, and push to carry that change up to GitHub. Make sure every collaborator pulls down this change.
- Only after you're sure your secret environment variable file is not on GitHub, generate new AWS keys according to Amazon's instructions, and add them to your secrets file. Find a secure, off-GitHub way to get your keys to each collaborator.
-
To get this going on heroku, you need to configure environment variables on heroku's server. Use
heroku config:set
to set theS3_BUCKET_NAME
,AWS_ACCESS_KEY_ID
, andAWS_SECRET_ACCESS_KEY
on your heroku server. (Copy these values from your.env
file.) -
Push your changes to heroku, and upload a file live!
Image still not loading? Here are some things to check:
- Is your image uploading? Check in the bucket.
- Are you getting an "Access Denied" error? Check that your AWS credentials are correct in your secrets file. Delete your old secret key and generate a new one, if you think you miscopied or mistyped.
- Are you getting other bogus stuff!?