Skip to content

Production Checklist

The internet is a hostile environment. Before deploying your Django project you should carefully review your settings to ensure your application is secure and performs well. Django provides a mix of built-in and optional features to help you prepare for production.

Many of these settings are highly sensitive. It is common practice to use a separate private settings module or environment variables for your production environment rather than committing secrets to your source code.

Automated Checks

Django provides a built-in management command to scan your project for common security issues. You should always run this command against your production settings file before going live.

bash
python manage.py check --deploy

Server Configuration

The runserver command is built exclusively for local development. It is not secure or efficient enough for a live environment. You must switch to a production-ready WSGI or ASGI server like Gunicorn or Daphne before deploying.

Critical Settings

SECRET_KEY

This key is used for cryptographic signing and must be kept completely secret. You should never hardcode this value in your settings file. Instead you can load it from an environment variable or a secure file on your server. If an attacker discovers your secret key they can compromise your entire application.

DEBUG

You must absolutely set DEBUG = False in production. Leaving it enabled leaks highly sensitive information about your source code and database structure whenever an error occurs.

Environment-Specific Settings

ALLOWED_HOSTS

When debug mode is disabled Django requires you to specify exactly which domain names your site can serve. This protects your application from certain security exploits. You must add your production domain name to this list.

DATABASES and CACHES

Your database and cache connection parameters will almost certainly change in production. You must protect your database passwords exactly like your secret key. You should also configure your firewall so that your database only accepts connections directly from your application server.

Also, set up backups for your database to avoid data loss.

STATIC_ROOT and MEDIA_ROOT

During development Django automatically serves your static and media files. In production you must define a STATIC_ROOT directory where the collectstatic command can gather your assets. Similarly you must ensure your MEDIA_ROOT is configured correctly so user uploads are stored securely. You must also configure your web server so it never attempts to execute user-uploaded media files.

EMAIL_BACKEND

If your application sends emails, you need to configure your mail server settings. You should also update the DEFAULT_FROM_EMAIL and SERVER_EMAIL settings to use a real email address instead of the default localhost addresses.

Security and HTTPS

Any website that handles user logins must enforce HTTPS across the entire domain. This prevents attackers from stealing session cookies or passwords over unsecured network connections. Once your web server is configured to handle HTTPS traffic you should update two specific settings.

Set both CSRF_COOKIE_SECURE and SESSION_COOKIE_SECURE to True. This instructs the browser to only send these sensitive cookies over secure HTTPS connections.

Performance Optimizations

Disabling debug mode automatically turns on several performance enhancements. You can tune a few extra settings to make your application even faster.

CONN_MAX_AGE

Enabling persistent database connections can drastically speed up your application. This setting keeps the database connection open for a specified duration rather than creating a new connection for every single web request.

TEMPLATES

When debug mode is disabled Django automatically caches your templates in memory. This improves performance significantly because the application does not have to read the template files from the hard drive for every request.

Sessions

If you rely heavily on sessions you can configure a caching backend to store them in memory rather than the database. If you continue using database-backed sessions you should regularly clear old expired sessions to free up storage space.

Error Reporting

Even well-tested code can encounter unexpected errors in production. You need a reliable way to track these issues.

ADMINS and MANAGERS

You can configure the ADMINS setting with a list of email addresses. Django will automatically email these addresses whenever the application crashes with a 500 server error. The MANAGERS setting works similarly but sends notifications for 404 broken link errors.

LOGGING

You should review your logging configuration to ensure important application events are recorded safely to a file or external service.

Custom Error Views

Django provides default templates for common HTTP errors. You should create custom 404.html and 500.html files in your root template directory to provide a better experience for your users when something goes wrong.

Custom User Model

Django strongly recommends setting up a custom user model. You can refer to this doc on how to set it up. Even if you're satisfied with the default User model, you should still create a custom user model as below:

python
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    pass

(Optional) Time Tracked Model

Often you would want to maintain the created_at and updated_at for each record of a model. For such use cases, consider creating a base Model that all other models can inherit from:

python
class TimeTrackedModel(Model):
    created_at = DateTimeField(auto_now_add=True)
    updated_at = DateTimeField(auto_now=True)

    class Meta:
        # This makes the model abstract, meaning no table will be created.
        abstract = True

uv package manager

Finally, consider using uv package manager to handle the project dependencies efficiently.