Rails 5, Paperclip and CloudFront


Rails 5, Paperclip and CloudFront

Paperclip has excellent documentation, but there is lack of information about running it with CloudFront. I will show you how to configure it + money-saving bonus!

CloudFront is an excellent CDN, which speed up and secure (SSL) access to files. To configure it in your application, you can set paperclip_defaults like below in config/production.rb file:

config.paperclip_defaults = {
  storage: :s3,
  path: ':class/:attachment/:id_partition/:style/:hash.:extension',
  url: ':s3_domain_url',
  s3_credentials: {
    bucket: ENV['S3_BUCKET'],
    access_key_id: ENV['AWS_ACCESS_KEY_ID'],
    secret_access_key: ENV['AWS_SECRET_KEY']
  },
  s3_host_alias: ENV['CDN_HOST'],
  s3_options: {
  region: ENV['AWS_REGION']
  }
}

In above example I used ENV for simplicity, but personally I prefer Figaro for configuration.

Cache uploaded files in a browser

Files uploaded by Paperclip don’t have set Cache-Control header by default and browsers’ downloads file every time. It can be wasted money if files are frequently accessed but doesn’t change (eg. CSS/JS files with hash in a name).

To prevent this behavior, you can set Cache-Control header to files during upload. To do this, add options to your Paperclip configuration in a model:

# configure how long browser should cache files
s3_headers: { 'Cache-Control' => "max-age=#{1.year.seconds}" }

Full example:

class MyPicture < ApplicationRecord
  has_attached_file :picture,
    styles: { big: '1000x800>', thumb: '350x350>' },
    s3_headers: { 'Cache-Control' => "max-age=#{1.year.seconds}" }
end