Stalk Stalk - 1 month ago 19
Python Question

Django + Gunicorn + Nginx: Bad Request (400) in Debug=True

I'm trying to run my server with Django, nginx and gunicorn. On the development Server, everything went fine. But on the production server, gunicorn always returns a Bad Request (400).

I'm aware that I need to set my

ALLOWED_HOSTS
variable, and I did. I tried the correct domain, an asterisk, or even setting DEBUG to True. But still, it's always Bad Request (400).

Here is my nginx-config:

server {
listen 80;

location /static {
alias /home/username/sites/sub.domain.example.com/static;
}

location / {
proxy_set_header Host $http_host;
proxy_pass http://localhost:8000;
}
}


My
wsgi-prod.py
file:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings_prod")

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()


The
settings_prod.py
file (shortened):

DEBUG = False
ALLOWED_HOSTS=["*"]


I start gunicorn the following way (with virtualenv):

gunicorn --bind 127.0.0.1:8000 app.wsgi_prod:application


When I start the server with
manage.py runserver --settings=app.settings_prod
, the site is accessible. gunicorn's error log shows nothing, and the access log only shows the 400. The static content does work.

Answer

You should tell Nginx to pass the host to Gunicorn like this:

proxy_set_header        Host            $host;

Additionally I would pass these values (example) also so you have access to the IP of the request:

proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

Please also check your Nginx Logs if you havenĀ“t done so. I hope this helps.

EDIT: Try also to set set server name like:

server_name     your_domain.com www.your_domain.com

Last but not least try to set your environment like this (solution in this case):

os.environ['DJANGO_SETTINGS_MODULE'] = "app.settings_prod"