DEV Community

Lucas Kuhn
Lucas Kuhn

Posted on

Syncing files from AWS S3 to local storage on Rails

I usually use Amazon S3 for storing images with Active Storage. There are some issues when pulling my database to work with it on localhost:

  • I don't want to accidentally delete something on S3
  • I don't want my localhost without images 🥲

I added this rake task to download files from S3 and format them in a way that works with local storage:

# lib/tasks/s3_to_local.rake  desc "Sync files from S3 bucket to local storage folder" task :s3_to_local do s3_bucket = "YOUR_S3_BUCKET" access_key_id = Rails.application.credentials.dig(:aws, :access_key_id) secret_access_key = Rails.application.credentials.dig(:aws, :secret_access_key) storage_folder = Rails.root.join('storage') storage_folder.mkpath system("AWS_ACCESS_KEY_ID=#{access_key_id} AWS_SECRET_ACCESS_KEY=#{secret_access_key} aws s3 sync s3://#{s3_bucket} #{storage_folder}") # Ignores sub_folders already created and .keep files images = storage_folder.children.select { |file| file.file? && !file.empty? } # Formats the file path of each image so ActiveStorage understands them using :local storage images.each do |path_name| dir, basename = path_name.split file_name = basename.to_s sub_folders = dir.join(file_name[0..1], file_name[2..3]) sub_folders.mkpath # Create the subfolder used by active_record path_name.rename(dir + sub_folders + basename) # Renames file to be moved into subfolder end end 
Enter fullscreen mode Exit fullscreen mode

What makes this tricky is that S3 storage has everything in the root of the bucket, and when using local storage with ActiveStorage, everything should be under a subfolder.

Also, you need AWS CLI for this to work:

brew install awscli 
Enter fullscreen mode Exit fullscreen mode

Basically copy this task into lib/tasks/s3_to_local.rake, add your bucket name, your AWS credentials, run rake s3_to_local and you're good to go

Top comments (1)

Collapse
 
giridharans profile image
Giridharan

Nice !!
But i want to Sync Digital Ocean to local storage not 'AWS'
Is it possible ?