43

I have two locations in nginx config that work:

location ^~ /media/ {
  proxy_pass http://backend.example.com;
}

location ^~ /static/ {
  proxy_pass http://backend.example.com;
}

How can I combine these two into one location?

What I have done already:

I tried this suggestion

location ~ ^/(static|media)/ {
  proxy_pass http://backend.example.com;
}

but it doesn't work for me.

Also, when I don't use backends, the following config is functioning properly:

location ~ ^/(static|media)/ {
  root /home/project_root;
}

update (some strings from the log)

xx.xx.xx.xx - - [31/Dec/2013:13:48:18 +0000] "GET /content/11160/ HTTP/1.1" 200 5310 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 OPR/18.0.1284.68"
xx.xx.xx.xx - - [31/Dec/2013:13:48:18 +0000] "GET /static/font-awesome/css/font-awesome.min.css HTTP/1.1" 404 200 "http://www.example.com/content/11160/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome$
xx.xx.xx.xx - - [31/Dec/2013:13:48:18 +0000] "GET /static/bootstrap/css/bootstrap.min.css HTTP/1.1" 404 200 "http://www.example.com/content/11160/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.$
xx.xx.xx.xx - - [31/Dec/2013:13:48:18 +0000] "GET /static/css/custom.css HTTP/1.1" 404 200 "http://www.example.com/content/11160/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/53$
xx.xx.xx.xx - - [31/Dec/2013:13:48:18 +0000] "GET /static/colorbox/colorbox.css HTTP/1.1" 404 200 "http://www.example.com/content/11160/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Sa$
xx.xx.xx.xx - - [31/Dec/2013:13:48:18 +0000] "GET /static/colorbox/jquery.colorbox-min.js HTTP/1.1" 404 200 "http://www.example.com/content/11160/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.$
xx.xx.xx.xx - - [31/Dec/2013:13:48:18 +0000] "GET /static/js/scripts.js HTTP/1.1" 404 200 "http://www.example.com/content/11160/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537$

SOLUTION

Actually my solution does work fine:

location ~ ^/(static|media)/ {
  root /home/project_root;
}

and the issue has nothing to do with backends. As Guido Vaccarella correctly noticed it just followed after another location ~ ... that matched, so that my location ~ ... had no chance to run.

Vlad T.
  • 555
  • 1
  • 4
  • 10
  • I don't see why your regex proxy pass doesn't work. What happens when you try it? – Grumpy Dec 30 '13 at 10:01
  • When I try it the frontend nginx throws 404 error. – Vlad T. Dec 30 '13 at 10:26
  • Is the ) at the end of the location statement just an error in your question or it's also in you configuration file? – Guido Vaccarella Dec 30 '13 at 10:46
  • You should double check rest of your config for errors. Additionally, might want to investigate why it's throwing a 404 by seeing where it's looking, what was missing. It's also possible that it throws 404 on the error document not being found and thus need to look at an earlier error thrown. – Grumpy Dec 31 '13 at 10:40
  • please provide the error from the error log – Mohammad AbuShady Dec 31 '13 at 11:16
  • Sorry for the delay, guys, it's all new year stuff, you know. @Guido Vaccarella yes, there is a closing bracket at the end. Do you think it's a mistake? – Vlad T. Dec 31 '13 at 13:43
  • @Grumpy The files are in place. As I said earlier, the image files and styles are shown when I use split location statements, no errors. – Vlad T. Dec 31 '13 at 13:46
  • @MohammadAbuShady added log records. – Vlad T. Dec 31 '13 at 13:59
  • Could you please also add the logs of the backend? – Guido Vaccarella Jan 01 '14 at 12:46
  • @GuidoVaccarella There are no records in the backend log when I combine two locations. Seems like frontend doesn't proxy requests to the backend. – Vlad T. Jan 01 '14 at 18:30
  • ok so basically what do you get? a different page or an error page? – Mohammad AbuShady Jan 01 '14 at 22:13
  • You seem to have posted your access log. Post your error log from nginx. – Grumpy Jan 02 '14 at 05:44
  • @MohammadAbuShady I get the standard nginx 404 error page. – Vlad T. Jan 02 '14 at 10:02
  • @Grumpy Hmmm... I just noticed that my nginx error log is empty (0 bytes). And I don't know why... – Vlad T. Jan 02 '14 at 10:03
  • In your working configuration you were using the ^~ prefix which tells nginx to stop serching after an url matches. I think there's another location directive matching the same pattern and preventig the one with the proxy_pass from working. Please double check your configuration for other location directives that may cause problems or post your whole configuration file so we can look into it. – Guido Vaccarella Jan 02 '14 at 14:41

2 Answers2

41

According to nginx documentation:

Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used.

In your configuration, the following location is defined before the one with the proxy_pass and it matches the request of js and css files under static:

  location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires max;
    log_not_found off;
  }

Unfortunately the "log_not_found off" clause disables the logging for any file-not-found error related to this location, that's why your error_log is empty!

You can try to comment out this location or move it after the location with the proxy_pass (if you need it for other files not in static / media).

Guido Vaccarella
  • 1,418
  • 14
  • 13
20
location ~ ^/(static|media)/ {
  proxy_pass http://backend.example.com;
)     <-----------

Should be...

location ~ ^/(static|media)/ {
  proxy_pass http://backend.example.com;
}     <-----------

The closing needs to be a brace {}, not a parenthesis bracket ().

Can't believe how long it took to see that. Guido was right from the comments.

Grumpy
  • 2,979
  • 18
  • 23
  • 1
    Oh, sorry for misunderstanding, I thought it was meant the bracket after "media" `|media)` in the string started with the "location". But wrong brace here is just a typo (corrected in question). Otherwise this nginx config wouldn't be loaded and would throw an error something like `unexpected ")"...` Sorry, again. – Vlad T. Jan 01 '14 at 08:06