HTTPS, TLS & DNS for Django in production
Domains, certificates, redirects, and the settings that make Django agree with its proxy about HTTPS.
A production site needs a domain that points at it, a valid certificate, and a Django configuration that knows the request arrived over HTTPS. The last part is the one most often missed.
The guides cover DNS records, Let’s Encrypt and renewals, CDNs such as Cloudflare in front, and the errors that appear when any link in that chain breaks.
Set it up
Guides that take this from nothing to running in production.
- Configure HTTPS for Django with Let's Encrypt
A Django app running over plain HTTP is not safe for production. Login sessions, admin access, CSRF tokens, API traffic, and password resets can all be exposed in transit if TLS...
- Point a Domain at Your Django Server (DNS Setup)
Connect a domain to a Django server: A and AAAA records, www and apex, CNAMEs for platforms, TTLs, verifying propagation with dig, and matching ALLOWED_HOSTS and certificates.
- Get a Wildcard Certificate for Django Subdomains
Issue a Let’s Encrypt wildcard certificate for *.example.com to serve Django on many subdomains: DNS-01 challenges with certbot DNS plugins or acme.sh, automatic renewal with provider API tokens, Nginx configuration, and Django host settings.
- Custom Domains With Automatic HTTPS for Django Tenants
Let SaaS customers point their own domains at a multi-tenant Django app with automatic HTTPS: Caddy on-demand TLS with an ask endpoint in Django, domain verification, tenant lookup by Host, and protecting against abuse and rate limits.
- Deploy Django with Caddy and Automatic HTTPS
If you want to deploy Django with Caddy in production, the main challenge is not just putting a reverse proxy in front of the app.
- Deploy Django Behind Cloudflare
Put Django behind Cloudflare correctly: Full (strict) TLS, origin lockdown, real client IPs, HTTPS detection, cache rules, and request limits.
- Expose Django with Cloudflare Tunnel
Serve a Django app through Cloudflare Tunnel with no open inbound ports: cloudflared setup, ingress rules, DNS routing, real client IPs, HTTPS settings, and protecting the admin.
- Automate HTTPS for Django on Kubernetes With cert-manager
Use cert-manager to issue and renew Let’s Encrypt certificates for a Django app on Kubernetes: install it with Helm, create a ClusterIssuer with HTTP-01 or DNS-01, request certificates through Ingress or Gateway annotations, and troubleshoot stuck challenges.
Run it well
Tuning, reliability, and operations once it works.
- Harden Nginx TLS for Django (SSL Labs A+)
Configure Nginx TLS for a Django site to earn an SSL Labs A+: TLS 1.2 and 1.3 only, modern ciphers, HSTS with Django settings, OCSP stapling, session settings, certificate chain, and verifying with SSL Labs and testssl.sh.
- Monitor TLS Certificate Expiry for Django Sites
Catch expiring HTTPS certificates before users do: check expiry from outside with uptime monitors, Prometheus blackbox exporter, or a scheduled script, cover every domain and certificate path, alert at 21 and 7 days, and verify that renewal actually reloads Nginx.
Check it
Review lists to run before launch or after a change.
- DNS Cutover Checklist for Moving a Django Site
A checklist for switching DNS when moving a Django site to a new server, host, or CDN: lower TTLs in advance, prepare TLS certificates and ALLOWED_HOSTS, sync data and freeze writes, switch records, verify from several locations, and keep the old host as a fallback.
- Django Security Headers Checklist
Check every HTTP security header a Django site should send: HSTS, CSP, frame options, nosniff, referrer and permissions policies, COOP, and cookie flags.
Fix it
Errors and symptoms, each traced to a cause and a fix.
- Fix Too Many Redirects with Django HTTPS Behind a Proxy
Fix ERR_TOO_MANY_REDIRECTS on Django behind Nginx, a load balancer, or Cloudflare: SECURE_PROXY_SSL_HEADER, forwarded headers, and duplicate redirects.
- Fix Let's Encrypt Certificate Renewal Failures
Fix Certbot renewal failures for Django sites on Nginx: dry runs, timer checks, HTTP-01 challenge paths, redirects, firewalls, DNS changes, and reload hooks.
- Fix CERTIFICATE_VERIFY_FAILED for Outbound Django Requests
Fix SSL CERTIFICATE_VERIFY_FAILED when Django calls external APIs: incomplete server chains, missing CA bundles in containers, certifi versus the system store, internal CAs, proxies, and clock skew.
- Fix Mixed Content Warnings on a Django HTTPS Site
Fix mixed content on a Django site served over HTTPS: find http:// resources, correct absolute URLs behind a proxy, fix storage and CDN URLs, rewrite stored content, and add upgrade-insecure-requests.
- Fix HTTPS Not Working for Django Behind Nginx
Fix a Django site where HTTPS does not load after installing a certificate: open port 443 in the firewall and cloud security group, add a listen 443 ssl block, check DNS and the certificate, and make Django aware of HTTPS.
- Fix SSL Certificate Name Mismatch for www and Apex Domains
Fix NET::ERR_CERT_COMMON_NAME_INVALID and certificate name mismatch errors on a Django site: issue one certificate for both www and the apex domain, redirect to a canonical host, and check DNS, SNI, and default server blocks.
- Fix Certbot "Challenge failed" When Issuing a Certificate
Fix Certbot Challenge failed for domain errors when getting a first Let's Encrypt certificate for Django: unauthorized 404 on the ACME path, DNS problems, closed port 80, Cloudflare proxying, and redirects that break HTTP-01.
- Fix Let's Encrypt "too many certificates" Rate Limits
Fix Let’s Encrypt rate limit errors such as too many certificates already issued for this exact set of domains and too many failed authorizations: stop reissuing on every deploy, persist certificates, and use the staging environment.
- 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 "You’re Accessing the Development Server Over HTTPS"
Fix the Django runserver error saying you’re accessing the development server over HTTPS but it only supports HTTP: clear cached HSTS, turn off SSL redirects in development, avoid .dev domains, and run local HTTPS properly when you need it.
- Fix ERR_SSL_PROTOCOL_ERROR on a Django Site
Fix the browser error ERR_SSL_PROTOCOL_ERROR or SSL_ERROR_RX_RECORD_TOO_LONG for a Django site: find which layer answers HTTPS with plain HTTP, fix listen 443 ssl in Nginx, port mappings, proxy upstream schemes, and cached HSTS for development servers.
- Fix Cloudflare 525 and 526 SSL Errors for a Django Site
Fix Cloudflare Error 525 SSL handshake failed and Error 526 invalid SSL certificate in front of Django: match the SSL/TLS mode to the origin, install a valid or Origin CA certificate on Nginx, open port 443, and check SNI and expiry.
- 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.
- 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 PostgreSQL SSL Connection Errors in Django
Fix Django PostgreSQL TLS errors: no pg_hba.conf entry with no encryption, server does not support SSL, root.crt missing for verify-full, certificate verify failed, and SSL SYSCALL EOF drops.
- Fix Nginx Showing the Default Page Instead of Django
Fix the Welcome to nginx page appearing instead of your Django site: enable the site, remove the default server, match server_name, add the HTTPS and IPv6 listeners, and reload after nginx -t.
- Fix Cloudflare 521 and 522 Errors for a Django Origin
Fix Cloudflare Error 521 web server is down and Error 522 connection timed out in front of Django: check that Nginx listens, allow Cloudflare IPs through the firewall, match the SSL mode to the origin, and fix origin DNS records.
- Fix Nginx "Cannot Load Certificate" for a Django Site
Fix Nginx emerg errors such as cannot load certificate BIO_new_file() failed, no such file, or key values mismatch: check certificate paths, Certbot live symlinks, file permissions, PEM formats, and that the key matches the certificate.
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.
- Hardening a Django deploymentClose the common gaps in settings, headers, the admin, the server, and the software supply chain.
- Keeping it runningLogs, errors, metrics, uptime, backups, and the runbooks you need before the first incident.