502 Bad Gateway with Nginx and Django

Hi, I installed the one click Django app with Ubuntu 16.04, and followed the tutorial here: Link

Getting to the end successfully, I see the “Hello, world! This is our first view.” when visiting my VPS IP address. I then got a DNS from freenom and pointed it to DigitalOceans nameservers as per this guide : Link

I can still connect via the IP address, but going to the domain name (my registered DNS) shows a 502 error.

I’ve tried the following:

  • Adding ALLOWED_HOSTS in the django
  • Changing/adding the server name in the available sites file
  • turning on/off proxy buffering
  • Changing proxy buffering settings
  • Deleting and rebuilding the droplet
  • Checking UFW settings

Nginx, gunicorn and django all seem to be working fine

The nginx error log is showing:

*16 upstream prematurely closed connection while reading response header from upstream, client:[my IP], server:, request: "GET /HTTP1.1", upstream: "http://unix:/home/django/gunicorn.socket:/", host: ""

Config files:

user www-data;
worker_processes auto;
pid /run/;

events {
	worker_connections 768;
	# multi_accept on;

http {

	# Basic Settings

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;

        proxy_buffering off;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	# SSL Settings

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	# Logging Settings

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	# Gzip Settings

	gzip on;
	gzip_disable "msie6";

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	# Virtual Host Configs

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;

#mail {
#	# See sample authentication script at:
#	#
#	# auth_http localhost/auth.php;
#	# pop3_capabilities "TOP" "USER";
#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
#	server {
#		listen     localhost:110;
#		protocol   pop3;
#		proxy      on;
#	}
#	server {
#		listen     localhost:143;
#		protocol   imap;
#		proxy      on;
#	}

Django settings for django_project project.

Generated by 'django-admin startproject' using Django 1.8.7.

For more information on this file, see

For the full list of settings and their values, see

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '[secret key]'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['', '', '[Droplet IP address']

# Application definition



ROOT_URLCONF = 'django_project.urls'

        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [

WSGI_APPLICATION = 'django_project.wsgi.application'

# Database

    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

# Internationalization



USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)

STATIC_URL = '/static/'
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
# Allow Django from all hosts. This snippet is installed from
# /var/lib/digitalocean/

import os
import netifaces

# Find out what the IP addresses are at run time
# This is necessary because otherwise Gunicorn will reject the connections
def ip_addresses():
    ip_list = []
    for interface in netifaces.interfaces():
        addrs = netifaces.ifaddresses(interface)
        for x in (netifaces.AF_INET, netifaces.AF_INET6):
            if x in addrs:
    return ip_list

# Discover our IP address
ALLOWED_HOSTS = ip_addresses()

upstream app_server {
    server unix:/home/django/gunicorn.socket fail_timeout=0;

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    client_max_body_size 4G;
    server_name [droplet IP];

    keepalive_timeout 5;
    proxy_ignore_client_abort on;

    # Your Django project's media files - amend as required
    location /media  {
        alias /home/django/django_project/django_project/media;

    # your Django project's static files - amend as required
    location /static {
        alias /home/django/django_project/django_project/static;

    # Proxy the static assests for the Django Admin panel
    location /static/admin {
       alias /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin/;

    location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_redirect off;
            proxy_buffering off;

            proxy_pass http://app_server;




PS. As default my django settings show SQLite as the database, but it’s supposed to use postgreSQL is this correct?

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Good morning Matt,

as I had the same problems as you, my solution was: ALLOWED_HOSTS = [ ‘domain_name’, ‘dropelt_IP’]

and add the bottom of

change: ALLOWED_HOSTS = ip_addresses()


ALLOWED_HOSTS += ip_addresses()

Maybe this solution works for you as well, if you haven’t solved your problem already.

Kind regards Moritz