Settings & secrets for Django in production
Production settings, environment variables, and secrets, and the errors Django raises when they are wrong.
Production settings and secrets decide whether Django is safe and whether it starts at all. Many production-only errors, from DisallowedHost to CSRF failures, are settings problems.
The guides cover structuring settings, loading secrets from the environment or a secret store, rotating keys, and fixing the errors that misconfiguration causes.
Set it up
Guides that take this from nothing to running in production.
- Configure Django Environment Variables for Production
Read Django settings from environment variables safely: typed parsing, fail-fast secrets, systemd and Docker env files, and verification.
- Manage Django Secrets in Production
Store, load, and rotate Django secrets: inventories, file-based secrets, systemd credentials, cloud secret managers, and SECRET_KEY_FALLBACKS.
- Create a Django Superuser in Production Without a Shell
Create the first Django admin user in production non-interactively: createsuperuser --noinput with DJANGO_SUPERUSER_ environment variables, one-off containers and Jobs, PaaS consoles, an idempotent management command, and securing the account afterwards.
- Split Django Settings for Development and Production
Organise Django settings for development, staging, and production: a settings package with base, dev, and prod modules, environment variables for secrets, DJANGO_SETTINGS_MODULE per environment, and tests that keep production settings safe.
- Configure Django Settings With django-environ
Use django-environ to read Django settings from environment variables and .env files: typed values for DEBUG and ALLOWED_HOSTS, DATABASE_URL and CACHE_URL parsing, required variables, safe .env handling, and when to skip .env in production.
- Load Django Secrets From AWS Secrets Manager
Load Django secrets such as SECRET_KEY and database passwords from AWS Secrets Manager: inject them into ECS and EKS as environment variables, fetch them at startup with boto3 and caching, grant least-privilege IAM, and rotate RDS credentials.
- Load Django Secrets From HashiCorp Vault
Use HashiCorp Vault for Django secrets: read KV secrets with hvac using AppRole or Kubernetes auth, render them with Vault Agent or the Vault Secrets Operator, issue dynamic PostgreSQL credentials, and handle lease renewal and restarts.
- Encrypt Django Secrets in Git With SOPS
Keep Django environment secrets encrypted in the repository with Mozilla SOPS and age: encrypt .env and YAML files, decrypt during deploys with Ansible or CI, use cloud KMS keys for teams, and keep keys out of Git.
- Manage Django Secrets With Doppler
Manage Django environment variables and secrets with Doppler: organize projects and configs per environment, inject secrets with doppler run locally and on servers, sync to Heroku, Render, Vercel, or Kubernetes, use service tokens in CI, and rotate safely.
- Manage Django Secrets With Infisical
Use Infisical, an open-source secrets manager, for Django: organize projects and environments, inject secrets with infisical run, authenticate servers and CI with machine identities, sync to Kubernetes and platforms, and self-host or use Infisical Cloud.
- Use Google Secret Manager With Django
Load Django secrets from Google Cloud Secret Manager: mount secrets as environment variables or files on Cloud Run, read them with the Python client on Compute Engine and GKE, grant least-privilege access to service accounts, and rotate secrets with versions.
- Use Azure Key Vault With Django
Load Django secrets from Azure Key Vault: use Key Vault references in App Service and Container Apps, read secrets with azure-identity and managed identities, mount them on AKS with the Secrets Store CSI driver, and rotate values without redeploying code.
- Load Django Settings From AWS SSM Parameter Store
Use AWS Systems Manager Parameter Store for Django configuration and secrets: store SecureString parameters under a path per environment, inject them into ECS task definitions, read them with boto3 on EC2 and Lambda, grant least-privilege IAM, and compare with Secrets Manager.
- Serve Django Under a URL Prefix (/app) Behind Nginx
Run Django under a subpath such as example.com/app behind Nginx: forward SCRIPT_NAME correctly, set FORCE_SCRIPT_NAME, STATIC_URL, and cookie paths, and avoid broken admin links, redirects, and CSRF errors.
- Use Docker Secrets With Django
Pass Django secrets to containers as files instead of environment variables: Docker Compose and Swarm secrets mounted at /run/secrets, the _FILE convention, reading them in settings, and keeping secrets out of images and docker inspect.
- Sync Django Secrets Into Kubernetes With External Secrets Operator
Use External Secrets Operator to load Django secrets from AWS Secrets Manager, Google Secret Manager, Azure Key Vault, Vault, or Infisical into Kubernetes Secrets: configure a SecretStore with workload identity, map keys, set refresh intervals, and roll pods on change.
Run it well
Tuning, reliability, and operations once it works.
- Configure Django Sessions for Production
Choose and tune Django's session backend for production: database, cached_db, cache, or signed cookies; cookie security flags; expiry; write frequency; and cleaning up expired sessions.
- Custom 404 and 500 Error Pages for Django in Production
Create custom 404, 500, 403, and 400 pages for a Django site in production: templates and handler views, a 500 page that cannot fail, static assets that load, Nginx error pages for when Django is down, and testing them with DEBUG off.
- Rotate the Django Database Password Without Downtime
Rotate PostgreSQL or MySQL credentials used by a Django app without outages: use two database roles or dual passwords, update secrets in the right order, restart web, Celery, and cron processes, handle PgBouncer, and automate rotation with Secrets Manager.
- Rotate the Django SECRET_KEY Safely
Rotate Django's SECRET_KEY without breaking sessions and password reset links: what the key signs, SECRET_KEY_FALLBACKS, a staged rollout, leak response, and third-party libraries that use the key.
- Manage Django Settings on Kubernetes With ConfigMaps and Secrets
Deliver Django configuration on Kubernetes: ConfigMaps for non-secret settings, Secrets for credentials, envFrom versus mounted files, rolling pods when values change, encryption at rest, and syncing from external secret managers.
- What to Do When Django Secrets Leak
Respond to a leaked Django SECRET_KEY, database password, or API key: assess exposure, rotate in the right order, use SECRET_KEY_FALLBACKS only when appropriate, invalidate sessions and tokens, purge Git history, and prevent the next leak.
Check it
Review lists to run before launch or after a change.
- Django Production Settings Checklist (DEBUG, ALLOWED_HOSTS, CSRF)
A lot of Django production incidents come from settings.py, not application code.
- Django check --deploy Explained: Every Warning and Fix
Understand every warning from python manage.py check --deploy: HSTS, SSL redirect, cookies, SECRET_KEY, DEBUG, ALLOWED_HOSTS, and when silencing is justified.
- Django Privacy and GDPR Production Checklist
A technical privacy checklist for Django in production: personal data inventory, logs and error tracking, cookies, retention and deletion including backups, exports, encryption, access control, and processors.
Fix it
Errors and symptoms, each traced to a cause and a fix.
- How to Fix DisallowedHost in Django Production
A DisallowedHost error in Django production means Django rejected the incoming Host header. This is a security check, not a random app failure.
- CSRF Verification Failed in Django Production: How to Fix It
CSRF Verification Failed in Django production usually appears after a deployment change that affects domains, HTTPS, cookies, or proxy headers.
- Django Works with DEBUG=True but Fails with DEBUG=False
Fix Django apps that break when DEBUG is turned off: ALLOWED_HOSTS, static files, manifest errors, error templates, email handlers, and hidden exceptions.
- Fix ImproperlyConfigured: SECRET_KEY Must Not Be Empty
Fix the SECRET_KEY must not be empty error in production: find where settings load, pass the key to systemd, Docker, CI, and cron, and avoid unsafe defaults.
- Fix Django Login Not Persisting Behind HTTPS
Fix Django logins that do not stick behind a proxy or HTTPS: secure cookies, HTTPS detection, cookie domains, SameSite, and shared session backends.
- Fix Django Links Using example.com (Sites Framework)
Fix password reset emails, sitemaps, and allauth links that point to example.com: update the Site record, set SITE_ID, handle multiple environments, and get https in generated links.
- Fix TemplateDoesNotExist in Django Production
Fix TemplateDoesNotExist that appears only in production: case-sensitive paths, TEMPLATES DIRS relative to the wrong directory, apps missing from INSTALLED_APPS, files excluded from images, and cached loaders.
- Fix Users Logged Out After a Django Deploy
Stop Django deploys from logging everyone out: a changed or per-process SECRET_KEY, cache-backed sessions lost on restart, changed cookie settings, and rotating keys safely with SECRET_KEY_FALLBACKS.
- Fix Django "received a naive datetime" Warnings
Fix the Django RuntimeWarning DateTimeField received a naive datetime while time zone support is active: use timezone.now, make parsed and imported datetimes aware, and set USE_TZ, TIME_ZONE, and database time zones correctly.
- Fix Django "Session data corrupted" Warnings
Fix the Django warning Session data corrupted and users being logged out: find SECRET_KEY changes and mismatches between servers, use SECRET_KEY_FALLBACKS for rotation, and align session engines and serializers.
- Fix Django "Bad Request (400)" With DEBUG Off
Fix the plain Bad Request (400) page Django returns in production: DisallowedHost from ALLOWED_HOSTS, invalid HTTP_HOST from health checks, oversized or malformed requests, missing CSRF origins, and how to log the real reason.
- Fix Wrong Times in Django Production: TIME_ZONE and USE_TZ
Fix Django showing times hours off in production: understand USE_TZ and UTC storage, set TIME_ZONE correctly, activate per-user time zones, render local times in templates, and stop cron and Celery schedules from drifting.
- Fix Django 500 Internal Server Error in Production
Find the real cause of a Django 500 error in production: where tracebacks go with DEBUG off, logging setup, common causes, safe reproduction, and verification.
- Fix Environment Variables Not Loaded in Docker Compose
Fix Django settings missing environment variables under Docker Compose: .env versus env_file, variable precedence, recreating containers, $ in values, build-time versus runtime, and docker compose config.
- Fix systemd EnvironmentFile Variables Not Reaching Django
Fix Django settings that miss variables from a systemd EnvironmentFile: file syntax rules, the '-' prefix, quoting, no variable expansion, daemon-reload versus restart, and checking a running process.
- Fix Celery Connecting to amqp://guest@localhost Instead of Redis
Fix Celery workers that log Cannot connect to amqp://guest@127.0.0.1:5672 when you configured Redis: load Django settings in celery.py, use the CELERY_ namespace correctly, and pass the broker URL to every process.
- Fix AppRegistryNotReady in Celery and Django Scripts
Fix Apps not loaded yet and settings not configured errors in Celery workers, cron scripts, and Gunicorn config: set DJANGO_SETTINGS_MODULE, call django.setup() first, and avoid early model imports.
- Fix Django Redirecting to localhost or the Wrong Host
Fix Django redirects that send users to localhost, 127.0.0.1, or an internal hostname behind Nginx or a load balancer: forward the Host header, use USE_X_FORWARDED_HOST correctly, and fix LOGIN_REDIRECT_URL and absolute URLs.
- Fix build_absolute_uri Returning http Instead of https
Fix Django request.build_absolute_uri and is_secure returning http behind an HTTPS proxy: set SECURE_PROXY_SSL_HEADER, forward X-Forwarded-Proto from Nginx or the load balancer, and fix OAuth callbacks, API pagination links, and emails.
- Fix OAuth redirect_uri_mismatch After Deploying Django
Fix Google, GitHub, and Microsoft OAuth redirect_uri_mismatch errors after deploying Django with django-allauth or social-auth: register the exact production callback URL, force https behind a proxy, and fix host and trailing-slash differences.
- Fix "CSRF_TRUSTED_ORIGINS Must Start With a Scheme" in Django
Fix the Django 4.0+ system check error 4_0.E001, which says CSRF_TRUSTED_ORIGINS values must start with a scheme: write full origins with https://, use wildcard subdomains correctly, parse the setting from environment variables, and avoid trailing slashes.
- Fix PostgreSQL "fe_sendauth: no password supplied" in Django
Fix the PostgreSQL error fe_sendauth no password supplied in Django: find why the password is empty, check DATABASE_URL parsing and environment loading in systemd, Docker, and cron, escape special characters, and use .pgpass or secrets safely.
- Fix Django LookupError: No Installed App With Label
Fix the Django LookupError no installed app with label in production, migrations, and Celery: add the app to INSTALLED_APPS, use the right app label, load the correct settings module, and avoid model imports before Django is ready.
- Fix Redis "NOAUTH Authentication Required" and WRONGPASS in Django
Fix Redis NOAUTH Authentication required and WRONGPASS invalid username-password pair errors in Django and Celery: put the password in the Redis URL correctly, URL-encode special characters, use ACL usernames, and keep cache and broker settings in sync.
- Fix Kubernetes CreateContainerConfigError for Django Pods
Fix Kubernetes CreateContainerConfigError for Django pods: find the missing Secret, ConfigMap, or key in the pod events, create it in the right namespace, fix envFrom and secretKeyRef names, and order resources so deploys do not race their config.
Learning paths through this topic
- Your first production deployment on a VPSFrom a fresh Ubuntu server to a Django site on HTTPS, with the settings and checks that keep it safe.
- Docker, from image to productionBuild a production image, run it with Compose, ship it from CI, and check the result.
- Hardening a Django deploymentClose the common gaps in settings, headers, the admin, the server, and the software supply chain.
- Django on KubernetesRun Django on a cluster with config, ingress, probes, jobs, graceful shutdown, and autoscaling, then package it with Helm and GitOps.