nginx not returning Cache-Control header from upstream gunicorn


nginx not returning Cache-Control header from upstream gunicorn



I'm using WhiteNoise to serve static files from a Django app running under gunicorn. For some reason, the Cache-Control and Access-Control-Allow-Origin headers returned by the gunicorn backend are not being passed back to the client through the nginx proxy.


Cache-Control


Access-Control-Allow-Origin



Here's what the response looks like for a sample request to the gunicorn backend:


% curl -I -H "host: www.myhost.com" -H "X-Forwarded-Proto: https" http://localhost:8000/static/img/sample-image.1bca02e3206a.jpg

HTTP/1.1 200 OK
Server: gunicorn/19.8.1
Date: Mon, 02 Jul 2018 14:20:42 GMT
Connection: close
Content-Length: 76640
Last-Modified: Mon, 18 Jun 2018 09:04:15 GMT
Access-Control-Allow-Origin: *
Cache-Control: max-age=315360000, public, immutable
Content-Type: image/jpeg



When I make a request for the same file via the nginx server, the two headers are missing.


% curl -I -H "Host: www.myhost.com" -k https://my.server.com/static/img/sample-image.1bca02e3206a.jpg

HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 02 Jul 2018 14:09:25 GMT
Content-Type: image/jpeg
Content-Length: 76640
Last-Modified: Mon, 18 Jun 2018 09:04:15 GMT
Connection: keep-alive
ETag: "5b27758f-12b60"
Accept-Ranges: bytes



My nginx config is pretty much what is documented in the gunicorn deployment docs, i.e. I haven't enabled nginx caching (nginx -T | grep -i cache is empty) or done anything else I would think is out of the ordinary.


nginx -T | grep -i cache



What am I missing?





does gunicorn actually get the request? can you see some sort of logs? maybe nginx just serves files himself? there is location / block in default config under your link.
– Alexandr Tatarinov
Jul 2 at 19:54



location /





You haven't enabled caching in Nginx and you want to know why it's not returning caching directives in it's response headers? A proxy server isn't just a pipe which your connection flows through unchanged to it's destination.
– miknik
Jul 2 at 22:19





@AlexandrTatarinov Yes! Thanks :-) I'm so used to defining a "location /static" in other scenarios that I assumed, because I had left it out, nginx was not handling the file. I forgot about "root"...
– Will Harris
Jul 3 at 6:59




2 Answers
2



The problem is that you have


location / {
try_files $uri @proxy_to_app;
}



directive in nginx config, so nginx just serves files himself and gunicorn doesn't even knows about it, and of course can't add headers.



It turns out I had forgotten the root directive I had configured many months ago, which was now picking up the static files. My error was in assuming that since I hadn't configured a location /static directive, nginx would be proxying all requests to the backend.


root


location /static



The solution for me was to remove the $uri reference from the try_files directive:


$uri


try_files


location / {
try_files /dev/null @proxy_to_app;
}



Alternatively, I could have simply put the contents of the @proxy_to_app location block directly inside the location / block.


@proxy_to_app


location /



Thanks to Alexandr Tatarinov for the suggestion in the comments.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?