我有一个Ruby on Rails站点,其中模型使用CarrierWave进行文件处理,目前使用的是本地存储。我想开始使用云存储,我需要将现有的本地文件迁移到云端。我想知道是否有人可以指出这样做的方法?
使用模型属性的加分点,允许我在后台逐行执行此操作,而不会中断我的网站以延长停机时间(换句话说,某些模型行仍然具有本地存储,而其他模型行使用云存储)。
我的第一直觉是为每个使用云存储的模型创建一个新的上传器,所以我在每个模型上有两个上传器,然后将文件从一个传输到另一个,设置一个属性来指示应该使用哪个文件,直到他们全部转移,然后删除旧的上传者。这似乎有点过分。
答案 0 :(得分:8)
最小可能零点Donwtime程序
在我看来,通过几乎没有停机时间来实现您想要的最简单,最快捷的方法是:(我将假设您将使用AWS云,但类似的程序适用于任何云服务)
s3cmd
(用于与S3交互的命令行工具)或GUI应用程序,将整个资产文件夹从文件系统复制到S3中的相应文件夹。:fog
存储的模型/上传器。请勿重新启动您的应用程序。而是调出rails控制台和模型,检查新资产URL是否正确且可按计划访问。例如,对于带有图片资源的视频模型,您可以这样检查:
Video.first.picture.url
这将根据更新的设置为您提供完整的云URL。复制URL并粘贴到浏览器中,以确保您可以正常使用。
如果这适用于每个具有资产的模型的至少一个实例,则可以重新启动应用程序。
重启后,您的所有资产都是通过云提供的,您的模型中不需要任何迁移或多个上传者。
(基于@Frederick Cheung的评论):使用s3cmd
(或类似的)rsync
或sync
资源文件夹从文件系统到S3来计算资产在步骤2和5之间上传的内容,如果有的话。
PS:如果您需要帮助为云存储设置carrierwave,请告诉我们。
答案 1 :(得分:2)
我会尝试以下步骤:
rails g migration MigrateFiles
这样的迁移,让carrierwave获取当前文件,处理它们并将它们上传到云端。如果您的模型如下所示:
class Video
mount_uploader :attachment, VideoUploader
end
迁移将如下所示:
@videos = Video.all
@videos.each do |video|
video.remote_attachment_url = video.attachment_url
video.save
end
如果执行此迁移,则应执行以下操作:
Carrierwave会下载每张图片,因为您为附件指定了一个远程网址(当前位置,如http://test.com/images/1.jpg)并将其保存到云中,因为您在上传器中对其进行了更改。
修改强>
由于San指出这不会直接起作用,你应该首先创建一个额外的列,运行迁移以将所有视频中的当前attachment_urls复制到该列,然后更改上传器并使用复制运行上述迁移在新专栏中的网址。使用另一个迁移只需再次删除该列。不是那么简单干净,而是在几分钟内完成。
答案 2 :(得分:1)
当我们使用Heroku时,大多数人建议使用cloudinary。免费且简单的设置。 我的情况是当我们使用cloudinary服务时,由于某些原因需要移入aws S3。
这就是我对上传者的所作所为:
class AvatarUploader < CarrierWave::Uploader::Base
def self.set_storage
if ENV['UPLOADER_SERVICE'] == 'aws'
:fog
else
nil
end
end
if ENV['UPLOADER_SERVICE'] == 'aws'
include CarrierWave::MiniMagick
else
include Cloudinary::CarrierWave
end
storage set_storage
end
另外,设置rake任务:
task :migrate_cloudinary_to_aws do
profile_image_old_url = []
Profile.where("picture IS NOT NULL").each do |profile_image|
profile_image_old_url << profile_image
end
ENV['UPLOADER_SERVICE'] = 'aws'
load("#{Rails.root}/app/uploaders/avatar_uploader.rb")
Profile.where("picture IS NOT NULL OR cover IS NOT NULL").each do |profile_image|
old_profile_image = profile_image_old_url.detect { |image| image.id == profile_image.id }
profile_image.remote_picture_url = old_profile_image.picture.url
profile_image.save
end
end
诀窍是如何通过env变量更改上传器提供程序。祝你好运!
答案 3 :(得分:0)
我已使用s3cmd将载波文件迁移到Amazon s3,并且可以使用。
以下是要执行的步骤:
sudo apt-get install s3cmd
上安装s3cmd s3cmd --configure
。
您需要在此处输入由Amazon提供的公共密钥和秘密密钥。s3cmd sync /path_to_your_files ://bucket_name/
--acl-public
以将文件上传为公共文件,并避免权限问题。注释:
sync
将不会重复您的记录。它将首先检查文件是否存在于远程服务器上。