Migrating Paperclip Image Assets from GCP Bucket to AWS S3 + Cloudfront
--
Migrating the storage layer for Rails Paperclip images need not be a hassle or lead to downtime.
Introduction
Paperclip is an attachment management library for Rails that despite being deprecated is still widely used. In one of my recent projects working with Solidus, we had to migrate our image assets from Google Cloud Storage to Amazon Web Services S3 with a Cloudfront CDN. I noticed a lack of guides on how to accomplish this so I will outline it below.
Migration
1. Prepare Code to Work with S3 + Cloudfront
In your environment configuration files (usually named development.rb
, production.rb
, etc) change your existing Paperclip configuration code to the one below:
config.paperclip_defaults = {
storage: :s3,
s3_region: ENV['AWS_REGION'],
s3_credentials: {
access_key_id: ENV['AWS_ACCESS_KEY'],
secret_access_key: ENV['AWS_SECRET_KEY']
},
s3_protocol: :https,
s3_host_alias: ENV['CLOUDFRONT_DOMAIN'].gsub('https://', ''),
use_accelerate_endpoint: true,
bucket: ENV['AWS_S3_IMAGE_BUCKET'],
s3_headers: {
'Cache-Control' => 'max-age=315576000'
}
}
The s3_host_alias
informs Paperclip that images should be downloaded from the CDN URL instead of the S3 bucket directly. use_accelerate_endpoint
may be useful for speeding up upload speed for users that are further from the bucket region. Setting a cache-control header is a good practice when working with a CDN.
In your Paperclip initializer (possibly in config/initializer/storage
) add the following lines of code:
Spree::Image.attachment_definitions[:attachment][:path] = 'spree/images/:id/:style/:basename.:extension'Spree::Image.attachment_definitions[:attachment][:url] = ':s3_alias_url'
The first line above configures the file path used for finding the images within the storage layer. The second line sets paperclip to use the s3_host_alias
we configured prior.