每次部署后,Paperclip文件被删除了。

4

我使用Paperclip gem存储图片,在本地环境下完美运行。然而,在我的线上应用中添加的任何图片在每次部署后都会被删除。

我使用Git进行部署。以下是我的部署流程:

$ bundle exec cap production deploy
$ ssh root@xx.xxx.xx.xxx
$ chmod -R 777 /rails_apps/app/releases
$ cd /rails_apps/app/current
$ cp config/database.yml.sample config/database.yml
$ RAILS_ENV=production bundle exec rake assets:precompile
$ /etc/init.d/apache2 restart

有其他人遇到过类似的情况吗?


更新:

这不是重复的问题,因为这个问题的答案是在我的 deploy.rb 中添加此行:

set :linked_dirs, fetch(:linked_dirs, []).push('public/system')

导致Paperclip完全崩溃。之前我曾经遇到过使用Paperclip时没有权限添加图片的问题,导致出现了以下错误:

Errno::EACCES in UsersController#update
Permission denied - /rails_apps/website/releases/20150807211111/public/system/users/avatars/000/000/562

但在我的服务器上运行此命令可以修复权限:

chmod -R 777 /rails_apps/website/releases

然而,按照上述修改我的deploy.rb文件会导致chmod -R 777命令不再起作用,我再次没有权限添加图片,结果出现相同的“Permission denied”错误。因此,该问题并未提供有效的解决方案。

1
可能是Capistrano删除Paperclip图像的重复问题。 - Justin
@JustinLicata 不是重复的问题;我编辑了以解释原因。 - Joe Morano
这并不是一个确切的答案,而是另一种解决方案。你想过把你的图片存储在S3桶里吗?这样做有许多优点原因。 - Justin
另外,您是否创建了指向该共享目录的符号链接?ln -s /rails_apps/website/shared/public/system /rails_apps/website/current/public/system。这里有一篇关于如何在Capistrano部署后更新权限的好文章 - Justin
你考虑过使用Git LFS吗?它可能有助于添加图像并使它们与您的项目保持一致。 - tjl
4个回答

5

最好的图片存储方式是像SWS安全、耐用和高度可扩展的对象存储这样的地方。

设置这个非常简单。

# Gemfile
gem 'paperclip'
gem 'aws-sdk 

在您的 config/environments/production.rb 文件中。
# config/environments/production.rb
config.paperclip_defaults = {
  :storage => :s3,
  :s3_credentials => {
    :bucket => ENV['S3_BUCKET_NAME'],
    :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
    :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
  }
}

如果您上传图片时遇到问题,请阅读以下两个配置部分。
如果问题仍然存在,请查看Paperclip文档页面以获取详细的配置选项。
要覆盖默认的URL结构并在URL中放置存储桶名称“域样式”(例如your_bucket_name.s3.amazonaws.com),可以将这些选项放置在上面显示的paperclip_defaults configuration哈希表中,或放置在初始化程序中。
#config/initializers/paperclip.rb
Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename'
Paperclip::Attachment.default_options[:s3_host_name] = 's3-us-west-2.amazonaws.com'

我希望这有所帮助。

愉快的编程!


有趣的想法。我认为这种方法不是免费的,我的理解正确吗? - Joe Morano
1
这是正确的,它不是免费的,但价格确实非常便宜。请参考 https://aws.amazon.com/s3/pricing/,每GB的费用为$0.0100。 - MZaragoza

4
你在这里要做什么:
set :linked_dirs, fetch(:linked_dirs, []).push('public/system')

实际上是通过符号链接将您的“public/system”文件夹从/rails_apps/website/releases/20150807211111/public/system链接到/rails_apps/website/shared/public/system,因此图片始终存储在共享目录中,不会在部署时丢失。因此,您实际上应该设置共享文件夹的适当权限。


哦,所以我实际上需要做的是运行类似于 chmod -R 777 /rails_apps/website/shared,而不是 chmod -R 777 /rails_apps/website/releasese - Joe Morano
应该可以正常工作,尽管我认为chmod 777对于你想要做的事情来说有点太开放了。最好保留原始权限,只将/rails_apps/website/内的所有内容chown给运行应用程序的用户。 - smallbutton
如果我想让任何人都能添加图片,你认为chmod -R 777是否合适? - Joe Morano
运行 chmod 命令会带来哪些负面影响?我独自拥有对服务器和计算机的访问权限。 - Joe Morano
你永远不知道。当然,我不会为文件授予任何人可执行权限。尽可能减少风险总是明智的选择。 - smallbutton
显示剩余2条评论

1
我假设你正在使用Capistrano,那么关于设置共享子目录,你怎么看?
#config/deploy.rb
set :shared_children, shared_children + %w{public/uploads}

然后,只需告诉Capistrano运行以下命令来正确设置共享文件夹:
cap deploy:setup

来源


我对Capistrano相当缺乏经验,我知道在服务器方面可能会出现很多问题...这些命令有没有可能导致不良后果,比如删除数据? - Joe Morano
@JoeMorano 如果您阅读我提到的源文章,您可以找到以下内容: “[cap deploy:setup] 准备一个或多个服务器进行部署。 … 在已经设置好的服务器上运行此任务是安全的;它不会破坏任何已部署的版本或数据。” - dombesz
另外,如果您不想这样做,您只需要将图像目录复制到共享目录,然后为自己创建符号链接即可。但您需要将符号链接作为后部署步骤添加,以在每次部署之后完成。同时,上述代码也可以实现相同的功能。 - dombesz

0

你可能正在使用不允许你在运行时直接将文件存储到文件系统的堆栈来托管你的应用程序。

像Heroku这样的服务只允许你将文件暂时存储到内存中,任何更新、重启或重新部署都会清除这些文件。我相信其他许多服务也是如此。

如果使用这样的服务,你需要将动态资产存储在一个单独的服务上,例如AWS-S3(亚马逊的简单存储服务)。你可以将文件存储在那里,并将这些资产的URL等信息存储在你的数据库中。


如果您能确定您的应用程序托管在哪里,我可以提供更详细的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接