通过paperclip gem上传到本地文件系统时出现权限被拒绝错误

时间:2014-07-06 21:36:04

标签: ruby-on-rails ruby-on-rails-4 paperclip permission-denied

我过去曾使用过paperclip与AWS S3存储,但在这个项目中,我试图减少外部依赖。我想将上传的图像保存到公共/资产目录,以便立即使用(绕过资产管道)。这是我在尝试保存时遇到的错误:

PostsController中的

Errno :: EPERM#update

Operation not permitted - /usr/local/src/project_name/public/assets/
...
app/controllers/posts_controller.rb:43:in `update'

我已根据现有的Stack Overflow解决方案的建议,将目录chmod到755。这不应该是重要的,因为瘦(我的Web服务器)以root身份运行(通过sudo),以便我可以绑定到443(HTTPS)。我不明白为什么甚至会出现root权限错误。我得不到什么?用户是在匿名公共帐户下上传文件,还是应用程序服务器以root用户身份保存文件?

其他信息:

环境:开发

操作系统:OS X 10.9.3

Ruby版本: MRI ruby​​ 1.9.3p194(2012-04-20修订版35410)[x86_64-darwin11.4.0]

宝石版本:

Gems included by the bundle:
  * actionmailer (4.0.3)
  * actionpack (4.0.3)
  * activemodel (4.0.3)
  * activerecord (4.0.3)
  * activerecord-deprecated_finders (1.0.3)
  * activesupport (4.0.3)
  * acts-as-taggable-on (3.2.6)
  * arel (4.0.2)
  * atomic (1.1.15)
  * bcrypt (3.1.7)
  * bcrypt-ruby (3.1.5)
  * builder (3.1.4)
  * bundler (1.5.3)
  * climate_control (0.0.3)
  * cocaine (0.5.3)
  * coffee-rails (4.0.1)
  * coffee-script (2.2.0)
  * coffee-script-source (1.7.0)
  * daemons (1.1.9)
  * epiceditor (0.2.2.1)
  * erubis (2.7.0)
  * eventmachine (1.0.3)
  * execjs (2.0.2)
  * faraday (0.9.0)
  * friendly_id (5.0.4)
  * haml (4.0.5)
  * haml-rails (0.5.3)
  * hike (1.2.3)
  * i18n (0.6.9)
  * jquery-rails (3.1.0)
  * json (1.8.1)
  * jwt (1.0.0)
  * mail (2.5.4)
  * mime-types (1.25.1)
  * minitest (4.7.5)
  * multi_json (1.8.4)
  * multi_xml (0.5.5)
  * multipart-post (2.0.0)
  * oauth (0.4.7)
  * oauth2 (0.9.4)
  * paperclip (4.1.1)
  * polyglot (0.3.4)
  * rack (1.5.2)
  * rack-test (0.6.2)
  * rails (4.0.3)
  * railties (4.0.3)
  * rake (10.1.1)
  * rdiscount (2.1.7.1)
  * sass (3.2.14)
  * sass-rails (4.0.1)
  * sorcery (0.8.5)
  * sprockets (2.11.0)
  * sprockets-rails (2.0.1)
  * sqlite3 (1.3.9)
  * thin (1.6.2)
  * thor (0.18.1)
  * thread_safe (0.2.0)
  * tilt (1.4.1)
  * treetop (1.4.15)
  * tzinfo (0.3.38)
  * uglifier (2.4.0)

文件权限(通过 ls -la public ):

drwxr-xr-x   9 proto  admin   306 Jul  6 15:16 .
drwxr-xr-x  23 proto  admin   782 Mar 28 06:24 assets

服务器守护程序(通过 ps aux | grep [t] hin ):

root 2650 0.0 0.9 2513704 79120 ?? S 3:43PM 0:07.81 thin server (0.0.0.0:443)

发布模型

class Post < ActiveRecord::Base
  # Relationships
  extend FriendlyId
  friendly_id :title, use: [:slugged, :history]
  has_attached_file :photo,
    path: ':rails_root/public/assets/',
     url: ':basename.:extension'
  belongs_to :author
  # Validations
  validates_presence_of :title, :body, :author_id, :slug
  validates_uniqueness_of :slug
  validates_attachment_content_type :photo, content_type: /\Aimage\/.*\Z/
  # Overriding this friendly method to update slug when title changes
  def should_generate_new_friendly_id?
    slug.blank? || title_changed?
  end
end

更新操作

def update
  @data = {
    title: params[:post][:title],
    body: params[:post][:body],
    photo: params[:post][:photo]
  }
  if @post.update! @data
    redirect_to @post
  else
    render :edit, layout: 'layouts/admin'
  end
end

表单部分

= form_for post, html: { multipart: true } do |f|
  = f.text_field :title, placeholder: 'Title'
  %br
  = f.text_area :body, class: 'hidden'
  #epiceditor
  %br
  = f.submit 'Save', class: 'button'
  - unless post.new_record?
    = link_to 'Delete', post, method: 'delete', class: 'button'
  = f.file_field :photo, class: 'upload'
- unless post.photo.nil?
  = link_to post.photo.url, post.photo.url

2 个答案:

答案 0 :(得分:0)

将公用文件夹的权限更改为775。

<强>更新

您可以在此处找到解决方案:Errno::EPERM (Operation not permitted FILE_PATH) when uploading image with Rails, Carrierwave, Amazon EC2

您可能需要将public/assets的所有者更改为root(或运行应用程序的用户)。

答案 1 :(得分:0)

写这个注释太长了,但你可以使用443之外的其他端口,root将从端口443重定向到,比方说iptables。

$ sudo iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

然后,您可以在端口8443上以rails用户的身份正常启动服务器

这当然是你想要的。

关于我提出问题的评论/问题,我不熟悉瘦服务器,但我会考虑应用程序以rails用户(proton?)和前端Web服务器作为root运行的情况。在这种情况下,root拥有的资产文件夹可能无法用于rails用户....