Websites & apps

Django production settings checklist before you deploy

Prepare a Django project for production on a VPS: DEBUG, SECRET_KEY, ALLOWED_HOSTS, HTTPS and proxy headers, static and media files, database, logging and manage.py check --deploy.

IntermediateLinux VPS3 min read

Most Django security and reliability problems in production come from settings left at their development defaults. Work through this Django production settings checklist before your first deploy and after big changes. Server setup (Gunicorn, Nginx, systemd) is covered in the linked deployment guides.

Before you start

  • A Django project you can run locally.
  • A way to provide environment variables on the server (systemd EnvironmentFile, a .env file read by django-environ, or Docker env files).

Core settings

import os

DEBUG = False
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
ALLOWED_HOSTS = ["example.com", "www.example.com"]
CSRF_TRUSTED_ORIGINS = ["https://example.com", "https://www.example.com"]
  • DEBUG = False: debug pages leak settings and code. Never enable it on a public server.
  • SECRET_KEY: unique per environment, from the environment, never in Git. Generate with python -c "from django.core.management.utils import get_random_secret_key as k; print(k())".
  • ALLOWED_HOSTS: required when DEBUG is off; otherwise every request returns 400.
  • CSRF_TRUSTED_ORIGINS: required for HTTPS form posts on Django 4+.

HTTPS behind Nginx

SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True

Nginx must send proxy_set_header X-Forwarded-Proto $scheme;, otherwise SECURE_SSL_REDIRECT causes an infinite redirect loop. Start HSTS with a short value (e.g. 3600) and raise it once HTTPS works everywhere.

Static and media files

STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
  • Run python manage.py collectstatic --noinput on each deploy.
  • Serve STATIC_ROOT and MEDIA_ROOT from Nginx with alias, or static files with WhiteNoise.
  • Back up MEDIA_ROOT: it holds user uploads, not in Git.

Database

  • Use PostgreSQL or MySQL, not SQLite, for multi-user production sites.
  • Read credentials from the environment (e.g. DATABASE_URL with dj-database-url).
  • Set CONN_MAX_AGE = 60 to reuse connections.
  • Run python manage.py migrate on deploy, after backups.

Caching and sessions

Configure Redis as the cache backend (built into Django 4+) and optionally cache-backed sessions:

CACHES = {"default": {"BACKEND": "django.core.cache.backends.redis.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1"}}

Logging and error reports

LOGGING = {
    "version": 1,
    "handlers": {"console": {"class": "logging.StreamHandler"}},
    "root": {"handlers": ["console"], "level": "WARNING"},
}

Console logs end up in journalctl when running under systemd. Set ADMINS and email settings to receive error emails, or use an error-tracking service.

Email

Set EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, EMAIL_USE_TLS and DEFAULT_FROM_EMAIL so password resets work.

Run the deployment check

DJANGO_SETTINGS_MODULE=myproject.settings python manage.py check --deploy

Django lists any remaining security warnings. Aim for none, or document why you accept each one.

Troubleshooting

  • Bad Request (400) on every page: ALLOWED_HOSTS does not include the domain.
  • Too many redirects: SECURE_SSL_REDIRECT without the proxy header setting or header.
  • CSRF verification failed on login: missing CSRF_TRUSTED_ORIGINS for the https origin.
  • Admin without CSS: collectstatic not run, or Nginx not serving STATIC_ROOT.

Django production FAQ

Should I use separate settings files?

Either separate files (base/dev/prod) or one file driven by environment variables works; never hard-code production secrets.

Is runserver acceptable behind Nginx?

No. Use Gunicorn or uWSGI; runserver is single-threaded and not hardened.

Can Django run on cPanel?

Yes, with Setup Python App and the same settings checklist.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.