5

I am using Pow and Nginx to serve my Rails 4 app in development. A simple file upload is returning 500 error and the request is not reaching the Rails controller. I assume this is the case because there is no mention of the request in the Rails log. Without any mention of the error, I am not sure what is going wrong here.

I started with an Ajax file upload but replaced it with a simple form which is also not working.

Tried this

Original Upload Button

and then went to this

Simple Upload Form

Current avatar.html.erb

<%= form_for @user, html: { multipart: true }, method: "post", url: '/settings/avatar/update', class: "", id: "update_avatar" do |f| %>
  <%= f.file_field :avatar, class: 'js-upload-photo-button js-change-avatar-btn', accept: 'image/png,image/gif,image/jpeg,image/jpg' %>
    <%= f.submit "Upload" %>
<% end %>

Request headers in Chrome

Full Request Headers

Expanded Request Headers section

Expanded Request Headers section

nginx.log

127.0.0.1 - - [01/Feb/2014:11:28:26 +0530] "POST /settings/avatar/update HTTP/1.1" 500 643 "https://allotrop.dev/settings/avatar" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"

pow access.log

[Sat Feb 01 2014 11:28:26 GMT+0530 (IST)] INFO [127.0.0.1] GET allotrop.dev /500.html

There are other questions here about Rails returning 500 error with no mention in log rails 500 error no production log entry , Rails 3.2.13, 500 error in development with no log and How to properly diagnose a 500 error (Rails, Passenger, Nginx, Postgres)

But these are one-off errors and do not seem related to the problem I am facing. It would be great if anyone can point me in the right direction.

Update 1

Relevant line from routes.rb

post '/settings/avatar/update', to: 'settings#update_avatar'

Update 2

Found my nginx error log. BTW, if you are using Homebrew, it is at /usr/local/Cellar/nginx/1.4.0/logs/error.log

nginx/error.log

2014/02/01 13:05:54 [crit] 8787#0: *85813 open() "/usr/local/var/run/nginx/client_body_temp/0000000010" failed (13: Permission denied), client: 127.0.0.1, server: *.dev, request: "POST /settings/avatar/update HTTP/1.1", host: "allotrop.dev", referrer: "https://allotrop.dev/settings/avatar"

2
  • Can you check with method: 'PATCH' in your form? If it doesn't will be good if you can update your routes file here. Commented Feb 1, 2014 at 7:00
  • Using Patch is not helping. I have added the relevant route in the question. Commented Feb 1, 2014 at 7:38

1 Answer 1

23

The problem is not with Rails but with Nginx which is pretty evident from the nginx error.log. This question helped me understand what I was dealing with - Rails 3 + carrierwave + nginx = permission denied.

Nginx uses the client_body_temp_path directive to specify the location where it will temporarily store the uploaded files from the user request. Homebrew had set it by default to /usr/local/var/run/nginx. This folder also contains fastcgi_temp, proxy_temp, scgi_temp and uwsgi_temp for me. Nginx worker processes run with user nobody and they were not able to access these folders. I chowned all these folders to the nobody user, but that did not help.

Finally, I did

client_body_temp_path /tmp/nginx/; inside the HTTP module of my nginx.conf to make it work.

Doing a ls -l shows

drwx------ 2 nobody wheel 68 Feb 1 14:44 nginx

I am not sure why this worked inside /tmp and not inside the original /var/run/nginx. I belive I will face similar issue when I use other temp folders or in production. Will update this thread if and when that happens.

I recommend symlinking the other relevant logs like the nginx access and error log, pow access and app log to the /log directory of your Rails app. It helps in looking up errors in one of these when you face a tricky bug.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you @movingahead, adding client_body_temp_path /tmp/nginx/; solved my issue as well :-)
Adding client_body_temp_path /tmp/nginx/; worked for me too!! this should be marked as the right answer.
Setting client_body_temp_path to anything under /tmp turned out to be unreliable because OS X would sometimes clean out these directories. I went back to investigate why the original defaults set up during install (under /usr/local/var/run/nginx) weren't working and found that nginx needs execute permissions to be set on all ancestor directories (source: nginxlibrary.com/403-forbidden-error). In my case, chmod o+x /usr/local/var fixed the issue without needing to change nginx.conf.
Had completely same issue, even chmodding the /usr/local/var/run/nginx folders did not resolve permission issue, but client_body_temp_path /tmp/nginx/; did anwer. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.