Migrate ảnh từ active storage local lên s3

Đăng bởi Lưu Đại vào ngày 24-01-2023

1. Vấn đề:

Một số ảnh của trang web này vẫn còn lưu trong locals (rails root storage). Mình muốn chuyển các ảnh này sang S3.

2. Việc cần làm: 

  • Tạo connect tới S3
  • Load các blob ra
  • Đẩy từng image của blob lên s3
  • Cập nhật lại service_name của các blob để từ sau nó load file từ s3
  • Xóa file cũ trên local (nợ làm sau chứ tối rồi)

3. Code:

Vào config/application.rb thêm dòng config sau
config.autoloader = :classic
Phải thêm cái này mới dùng được ActiveStorage::Blob trong file rake. Issue liên quan tới cái này ở đây

Tạo một rake task như sau: 
namespace :migrate_active_storage_local_to_s3 do
  desc 'Migrate ActiveStorage local files to S3'

  task migrate: :environment do
    # create connect to bucket
    credentials = Aws::Credentials.new(Rails.application.credentials.dig(:aws, :access_key_id), Rails.application.credentials.dig(:aws, :secret_access_key))
    s3 = Aws::S3::Resource.new(region: ENV.fetch('S3_REGION'), credentials: credentials)
    bucket = s3.bucket(ENV.fetch('S3_BUCKET'))

    # Migrate from local disk to s3
    local_blobs = ActiveStorage::Blob.where(service_name: 'local')

    local_blobs.each do |blob|
      blob.open do |file|
        bucket.object(blob.key).put(body: file)
      end
    end

    local_blobs.update_all(service_name: 'amazon')
  end
end
Đoạn kết nối tới bucket sử dụng API của gem aws-sdk-s3