I recently added the ability to give each one of my posts a photo. It makes the entire site a bit less boring and gives it some human feel. I found the excellent paperclip plugin from the thoughtbot guys. This allowed me to easily attach pictures, have them resized and display them along side my posts. However, I ran into some problems with managing the upload files, no worries, Amazon S3 to the rescue.
Capistrano Deployment Problems
Each time you deploy your updated rails app with capistrano, it checks out the code in a new time-stamped directory and symlinks it to a “current” directory. The problem with this setup was that each time I updated my code, the uploaded files would be wiped out. I had a few options:
- Tell paperclip to store the files above the document root
- Pretty simple, have to change the deploy recipe a bit
- Change my deploy recipe so “save” the files that have already been uploaded
- Kinda cumbersome and a little “wrong” feeling
- Tell paperclip to store the files on Amazon’s S3
- No changes to my filesystem or deploy recipe!
Paperclip Setup
In my Post model I’ve got
1 2 3 4 5 6 7 8 9 10 | has_attached_file :photo, :styles => { :tiny => "35x35", :preview => "175x175", :large => "300x300" }, :storage => :s3, :s3_credentials => "#{RAILS_ROOT}/config/s3.yml", :path => ":attachment/:id/:style.:extension", :bucket => 'lengelzigich_blog_buckit' |
I’m telling the paperclip plugin to resize my uploaded image in a few formats and also telling it that I want to store the files using S3 rather than the file system. I’ve added my amazon S3 key/secret code to a simple yaml file and I’m all set. Almost.
Install right_aws gem
Didn’t realize this right away but needed to install the right_aws gem.

{ 6 comments… read them below or add one }
Another option for you would have been to symlink the folder where you want to store your images. In most cases and files that need to persist across deploys will go in the “shared” folder inside your deploy path.
This little capistrano recipe does just that:
task :after_symlink do run "ln -nfs #{shared_path}/images/products #{release_path}/public/images/" endThis post answered my questions about the s3 storage option. Thanks a bunch!
The newest version of paperclip now has the default filesystem storage path as “:rails_root/public/system/:attachment/:id/:style/:filename”. This solves the problem that you had because, if you use Capistrano, the “system” folder is already symlinked from your “public” folder.
Thanks for the S3 help, though! Just what I was looking for.
Great S3 and Paperclip walkthrough, thanks for the post!
I should really do an updated one of these since it’s so old, but thanks!
Thanks – I used this post to set up paperclip with s3, and it works, but I do get some application errors if I call @model.attachment.exists? in the code.
The error goes something like “Key can not be blank.”
A workaround is to check to see if @model.attachment_file_name.blank? instead, since it won’t have a file name if the attachment doesn’t exist, but I was wondering if anyone else has had this same problem with referring directly to the attachment, and if so how did you fix it?
Awesome, I’ve been meaning to push off my picture storage to S3 on one of my apps for a while, I’m about to finally take the plunge thanks to this. Thanks!