【问题标题】:Paperclip files get deleted after each deploy回形针文件在每次部署后被删除
【发布时间】:2015-08-11 20:11:36
【问题描述】:

我使用 Paperclip gem 来存储图片,在 localhost 上它可以完美运行。但是,我添加到实时应用中的所有图片在每次部署后都会被删除。

我使用 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

有没有其他人遇到过这样的事情?


更新:

这不是重复的,因为this question的答案,就是在我的deploy.rb中加入这一行:

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

导致回形针完全折断。以前我遇到过没有权限使用回形针添加图像的问题,导致此错误:

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 命令不再起作用,并且我再次没有添加图像的权限,导致同样的“权限被拒绝”错误。

所以这个问题不能为我的问题提供有效的解决方案。

【问题讨论】:

  • @JustinLicata 不是重复的;我编辑解释了原因。
  • 这本身并不是一个答案,而是一个不同的解决方案。您是否考虑过将图像存储在 S3 存储桶中?这样做有许多有利的理由。
  • 另外,您是否创建了指向该共享目录的符号链接? ln -s /rails_apps/website/shared/public/system /rails_apps/website/current/public/system。这是另一个good post,关于如何在 Capistrano 部署后更新权限。
  • 你考虑过git lfs吗?添加图像并让它们与您的项目保持一致可能会有所帮助

标签: ruby-on-rails git deployment paperclip assets


【解决方案1】:

存储图像的最佳方式是SWS Secure, Durable & Highly-Scalable Object Storage 之类的地方

设置非常简单

# 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'

我希望这会有所帮助。

快乐的黑客

【讨论】:

  • 有趣的想法。我认为这种方法不是免费的是否正确?
  • 这是正确的,它不是免费的,但它真的很便宜aws.amazon.com/s3/pricing艺术每 GB 0.0100 美元
【解决方案2】:

你在这里做什么:

set :linked_dirs, fetch(:linked_dirs, []).push('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
  • 它应该可以工作,是的,虽然我发现chmod 777 对你想做的事情有点开​​放。最好将原始权限和 chown /rails_apps/website/ 中的所有内容留给运行应用程序的用户。
  • 如果我希望任何人都能够添加图片,您认为chmod -R 777 合适吗?
  • 不要将系统权限与您在应用程序中的权限混为一谈。作为启动 rails 进程写入图像的系统用户,只有该系统用户需要设置权限。您在应用内做什么(例如与设计用户)取决于您。
  • chown -R user:user /rails_apps/website/ 其中user 是运行rails 应用程序的系统用户。就这么简单。
【解决方案3】:

我假设您使用的是 capistrano,那么设置共享子项怎么样:

#config/deploy.rb
set :shared_children, shared_children + %w{public/uploads}

然后告诉 capistrano 在运行时正确设置共享文件夹:

cap deploy:setup

Source

【讨论】:

  • 我对 capistrano 相当缺乏经验,我知道服务器可能会出现很多问题......这些命令是否有可能导致不良后果,例如删除数据?
  • @JoeMorano 如果您阅读我提到的源文章,您可以找到:"[cap deploy:setup] prepares one or more servers for deployment. … It is safe to run this task on servers that have already been set up; it will not destroy any deployed revisions or data."
  • 另外,如果您不想这样做,您可以简单地将图像目录复制到共享目录,然后为自己创建一个符号链接。但是您需要将符号链接添加为部署后步骤,在每次部署后完成。上面的代码也是一样的。
【解决方案4】:

您可能将应用托管在不允许您在运行时将文件直接存储到文件系统的堆栈上。

Heroku 等服务仅允许您将文件临时存储到内存中的系统中,任何更新、重新启动、重新部署都会将其清除。我敢肯定,许多其他服务也是如此。

如果使用此类服务​​,您需要将动态资产存储在单独的服务上,例如 AWS-S3(亚马逊的简单存储服务)。您将文件存储在那里,并将这些资产的 url 等信息存储在您的数据库中


如果您确定托管应用的位置,我可以在解决方案中提供更详细的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    相关资源
    最近更新 更多