You deploy with nginx and Gunicorn and your site uses HTTPS. If Django occasionally returns HttpResponseRedirect or similar, you may find that the redirect sends you back to HTTP. Here’s how to fix it.
In the nginx configuration (inside the
location block), specify this:
proxy_redirect off; proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off statement tells nginx that, if the backend returns an HTTP redirect, it should leave it as is. By default, nginx assumes the backend is stupid and tries to fix the response; if, for example, the backend returns an HTTP redirect that says “redirect to http://localhost:8000/somewhere”, nginx replaces it with something similar to “http://yourowndomain.com/somewhere”. But Django isn’t stupid (or it can be configured to not be stupid), and it will typically return a relative URL. If nginx attempts to “fix” the relative URL, it will likely break things. Instead, we use
proxy_redirect off so that nginx merely passes the redirection as is.
The second line is only necessary if your Django project ever uses
request.is_secure() or similar. It’s a good idea to have it because even if it doesn’t today it will tomorrow, and it does no harm. Django does not know whether the request has been made through HTTPS or plain HTTP; nginx knows that, but the request it subsequently makes to the Django backend is always plain HTTP. We tell nginx to pass this information with the
X-Forwarded-Proto HTTP header, so that related Django functionality such as
request.is_secure() works properly. You will also need to set
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') in your