Skip to content

Django Settings Optimization Guide

File: settings-optimization.md
Description: Comprehensive guide to Django settings optimization for production and development environments
Author: Barodybroject Team team@barodybroject.com
Created: 2025-10-27
Last Modified: 2025-10-27
Version: 2.0.0

Table of Contents

Overview

The Django settings.py file has been completely rewritten and optimized for enterprise-grade production deployment while maintaining excellent developer experience. This optimization transforms approximately 500 lines of unorganized configuration into 950+ lines of well-structured, documented, and secure settings.

Key Achievements

  • Enterprise Security: Production-grade security with AWS Secrets Manager integration
  • High Performance: Optimized caching, database pooling, and static file handling
  • Environment Parity: Consistent behavior across development, staging, and production
  • Developer Experience: Simplified development setup with comprehensive debugging
  • Maintainability: Clear structure, comprehensive documentation, and type safety
  • Scalability: Configured for horizontal scaling and high-traffic scenarios

Architecture & Design Principles

12-Factor App Compliance

The configuration strictly follows 12-Factor App principles:

  1. Codebase: Single codebase with environment-specific configuration
  2. Dependencies: Explicit dependency declaration via requirements files
  3. Config: Configuration stored in environment variables
  4. Backing Services: Treat databases, caches, and queues as attached resources
  5. Build/Release/Run: Strict separation of build and run stages
  6. Processes: Execute as stateless processes
  7. Port Binding: Self-contained service with port binding
  8. Concurrency: Scale out via the process model
  9. Disposability: Fast startup and graceful shutdown
  10. Dev/Prod Parity: Keep development and production as similar as possible
  11. Logs: Treat logs as event streams
  12. Admin Processes: Run admin/management tasks as one-off processes

Security-First Design

  • Defense in Depth: Multiple layers of security controls
  • Secure by Default: Production security enabled by default with development overrides
  • Least Privilege: Minimal permissions and access controls
  • Zero Trust: No implicit trust, verify everything
  • Fail Secure: Security failures result in denial rather than access

Performance-Oriented Architecture

  • Caching Strategy: Multi-layer caching with Redis and local memory
  • Database Optimization: Connection pooling and query optimization
  • Static Asset Optimization: CDN-ready asset management
  • Lazy Loading: Components loaded only when needed
  • Efficient Resource Management: Optimized memory and CPU usage

Configuration Structure

The settings.py file is organized into logical sections for maintainability:

# ==============================================================================
# BASE CONFIGURATION
# ==============================================================================
# Core Django setup, paths, and environment detection

# ==============================================================================
# AWS SECRETS MANAGER CONFIGURATION  
# ==============================================================================
# Secure secrets management for production environments

# ==============================================================================
# SECURITY CONFIGURATION
# ==============================================================================
# Security headers, SSL, CSRF, and authentication security

# ==============================================================================
# ENVIRONMENT-SPECIFIC CONFIGURATION
# ==============================================================================
# Allowed hosts, CSRF origins, and container-specific settings

# ==============================================================================
# APPLICATION CONFIGURATION
# ==============================================================================
# Django applications, middleware stack, and URL configuration

# ==============================================================================
# DATABASE CONFIGURATION
# ==============================================================================
# Database engines, connection pooling, and optimization

# ==============================================================================
# TEMPLATE CONFIGURATION
# ==============================================================================
# Template engines, loaders, and context processors

# ==============================================================================
# AUTHENTICATION CONFIGURATION
# ==============================================================================
# User authentication, password validation, and authorization

# ==============================================================================
# EMAIL CONFIGURATION
# ==============================================================================
# Email backends and SMTP configuration

# ==============================================================================
# LOGGING CONFIGURATION
# ==============================================================================
# Structured logging, formatters, and handlers

# ==============================================================================
# SESSION AND CACHING CONFIGURATION
# ==============================================================================
# Session management and caching strategies

# ==============================================================================
# ALLAUTH AND SOCIAL AUTHENTICATION
# ==============================================================================
# Social authentication providers and multi-factor authentication

# ==============================================================================
# INTERNATIONALIZATION CONFIGURATION
# ==============================================================================
# Language support, localization, and timezone settings

# ==============================================================================
# STATIC FILES AND MEDIA CONFIGURATION
# ==============================================================================
# Static file serving, media uploads, and CDN integration

# ==============================================================================
# CMS AND CONTENT CONFIGURATION
# ==============================================================================
# Django CMS settings and content management

# ==============================================================================
# MARTOR (MARKDOWN EDITOR) CONFIGURATION
# ==============================================================================
# Markdown editor settings and customization

# ==============================================================================
# APPLICATION-SPECIFIC CONFIGURATION
# ==============================================================================
# Custom application settings and third-party integrations

# ==============================================================================
# PERFORMANCE AND OPTIMIZATION
# ==============================================================================
# Production performance optimizations and monitoring

Environment Management

Environment Detection

# Determine environment based on multiple indicators
IS_PRODUCTION = env.bool('RUNNING_IN_PRODUCTION', default=False)
DEBUG = env.bool('DEBUG', default=not IS_PRODUCTION)

# Environment-specific behavior
if IS_PRODUCTION:
    # Production optimizations
    SECURE_SSL_REDIRECT = True
    SECURE_HSTS_SECONDS = 31536000
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True
else:
    # Development conveniences
    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
    INTERNAL_IPS = ['127.0.0.1', 'localhost']

Environment Variables

Development Environment (.env)

# Environment Control
RUNNING_IN_PRODUCTION=False
DEBUG=True
LOG_LEVEL=DEBUG

# Database Configuration  
DB_CHOICE=postgres
DB_HOST=localhost
DB_PORT=5432
DB_NAME=barodydb
DB_USER=postgres
DB_PASSWORD=postgres

# Email Configuration
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend

# Debug Tools
ENABLE_DEBUG_TOOLBAR=False
DEBUGPY_PORT=5678

# Social Authentication (Development)
GITHUB_CLIENT_ID=your-dev-client-id
GITHUB_CLIENT_SECRET=your-dev-client-secret

Production Environment

# Environment Control
RUNNING_IN_PRODUCTION=True
DEBUG=False
LOG_LEVEL=INFO

# Security
SECRET_KEY=your-ultra-secure-secret-key-here
USE_HTTPS=True

# Database Configuration
DB_CHOICE=postgres
DB_HOST=your-db-host
DB_PORT=5432
DB_NAME=your-production-db
DB_USER=your-db-user
DB_PASSWORD=your-secure-db-password
DB_SSL_MODE=require

# AWS Services
AWS_ACCESS_KEY_ID=your-aws-access-key
AWS_SECRET_ACCESS_KEY=your-aws-secret-key
AWS_REGION=us-east-1

# Redis Cache
REDIS_URL=redis://your-redis-host:6379/1

# Email Configuration
EMAIL_BACKEND=django_ses.SESBackend
AWS_SES_REGION_NAME=us-east-1

# Social Authentication (Production)
GITHUB_CLIENT_ID=your-prod-client-id
GITHUB_CLIENT_SECRET=your-prod-client-secret

# Container Configuration
ALLOWED_HOSTS=your-domain.com,www.your-domain.com
CONTAINER_APP_NAME=your-app-name

Security Configuration

Production Security Features

HTTPS and Transport Security

if IS_PRODUCTION:
    # Force HTTPS
    SECURE_SSL_REDIRECT = env.bool('USE_HTTPS', default=True)
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

    # HTTP Strict Transport Security
    SECURE_HSTS_SECONDS = 31536000  # 1 year
    SECURE_HSTS_INCLUDE_SUBDOMAINS = True
    SECURE_HSTS_PRELOAD = True

    # Content Security
    SECURE_CONTENT_TYPE_NOSNIFF = True
    SECURE_BROWSER_XSS_FILTER = True
    X_FRAME_OPTIONS = 'DENY'
if IS_PRODUCTION:
    # Secure session cookies
    SESSION_COOKIE_SECURE = True
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_SAMESITE = 'Lax'
    SESSION_COOKIE_AGE = 3600  # 1 hour

    # Secure CSRF cookies
    CSRF_COOKIE_SECURE = True
    CSRF_COOKIE_HTTPONLY = True
    CSRF_COOKIE_SAMESITE = 'Lax'

AWS Secrets Manager Integration

def get_secret(secret_name: str = "barodybroject/env", region_name: str = "us-east-1") -> Dict:
    \"\"\"
    Retrieve secrets from AWS Secrets Manager with comprehensive error handling
    \"\"\"
    if not IS_PRODUCTION or not env.str('AWS_ACCESS_KEY_ID', default=''):
        return {}

    try:
        session = boto3.session.Session()
        client = session.client(service_name="secretsmanager", region_name=region_name)

        response = client.get_secret_value(SecretId=secret_name)
        secrets = json.loads(response["SecretString"])

        logging.info(f"Successfully loaded secrets from AWS Secrets Manager: {secret_name}")
        return secrets

    except ClientError as e:
        # Handle specific AWS errors
        error_code = e.response.get("Error", {}).get("Code", "Unknown")
        error_messages = {
            "DecryptionFailureException": "Unable to decrypt the secret",
            "ResourceNotFoundException": "Secret not found in AWS Secrets Manager",
            "InvalidParameterException": "Invalid parameter provided to AWS Secrets Manager",
            "InvalidRequestException": "Invalid request to AWS Secrets Manager",
        }

        error_msg = error_messages.get(error_code, f"AWS Secrets Manager error: {error_code}")
        logging.warning(f"AWS Secrets Manager error: {error_msg}")

        if IS_PRODUCTION and env.str('AWS_ACCESS_KEY_ID', default=''):
            raise ImproperlyConfigured(f"Failed to load production secrets: {error_msg}")

        return {}

Development Security

Relaxed Security for Development

if not IS_PRODUCTION:
    # Allow HTTP in development
    SECURE_SSL_REDIRECT = False
    SESSION_COOKIE_SECURE = False
    CSRF_COOKIE_SECURE = False

    # Enable debug features
    if env.bool('ENABLE_DEBUG_TOOLBAR', default=False):
        INSTALLED_APPS.append('debug_toolbar')
        MIDDLEWARE.insert(0, 'debug_toolbar.middleware.DebugToolbarMiddleware')

Database Optimization

Production Database Configuration

PostgreSQL with Connection Pooling

if DB_CHOICE == 'postgres':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': env.str('DB_NAME', default='barodydb'),
            'USER': env.str('DB_USER', default='postgres'),
            'PASSWORD': env.str('DB_PASSWORD', default=''),
            'HOST': env.str('DB_HOST', default='localhost'),
            'PORT': env.str('DB_PORT', default='5432'),
            'OPTIONS': {
                'sslmode': env.str('DB_SSL_MODE', default='prefer'),
                'application_name': env.str('CONTAINER_APP_NAME', default='barodybroject'),
                'connect_timeout': 60,
                'options': '-c statement_timeout=30000',  # 30 seconds
            },
            'CONN_MAX_AGE': 600,  # 10 minutes connection reuse
            'CONN_HEALTH_CHECKS': True,  # Enable connection health checks
        }
    }

    # Production connection pool settings
    if IS_PRODUCTION:
        DATABASES['default']['OPTIONS'].update({
            'MAX_CONNS': 20,
            'MIN_CONNS': 5,
        })

Development Database

This project is PostgreSQL-only. Any older SQLite examples are deprecated.

Database Performance Optimization

Query Optimization

# Enable persistent connections
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# Database transaction settings
ATOMIC_REQUESTS = False  # Per-view transactions for better performance
DATABASE_ENGINE_OPTIONS = {
    'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
    'charset': 'utf8mb4',
}

Caching Strategy

Multi-Layer Caching Architecture

Production Redis Caching

if IS_PRODUCTION:
    try:
        from django.core.cache.backends.redis import RedisCache

        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.redis.RedisCache',
                'LOCATION': env.str('REDIS_URL', default='redis://127.0.0.1:6379/1'),
                'KEY_PREFIX': 'barodybroject',
                'TIMEOUT': 300,  # 5 minutes default
                'VERSION': 1,
            }
        }

        # Enable cache middleware for production
        MIDDLEWARE.insert(1, 'django.middleware.cache.UpdateCacheMiddleware')
        MIDDLEWARE.append('django.middleware.cache.FetchFromCacheMiddleware')

        CACHE_MIDDLEWARE_ALIAS = 'default'
        CACHE_MIDDLEWARE_SECONDS = 600  # 10 minutes
        CACHE_MIDDLEWARE_KEY_PREFIX = 'barodybroject'

    except ImportError:
        # Fallback to database cache if Redis is not available
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'cache_table',
                'TIMEOUT': 300,
                'OPTIONS': {
                    'MAX_ENTRIES': 10000,
                    'CULL_FREQUENCY': 3,
                }
            }
        }

Development Local Memory Cache

else:
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
            'LOCATION': 'barodybroject-dev-cache',
            'TIMEOUT': 60,  # 1 minute for development
            'OPTIONS': {
                'MAX_ENTRIES': 1000,
                'CULL_FREQUENCY': 3,
            }
        }
    }

Template Caching

Production Template Optimization

if IS_PRODUCTION:
    # Template caching for production
    TEMPLATES[0]['OPTIONS']['loaders'] = [
        ('django.template.loaders.cached.Loader', [
            'django.template.loaders.filesystem.Loader',
            'django.template.loaders.app_directories.Loader',
        ]),
    ]

Logging & Monitoring

Comprehensive Logging Configuration

Structured Logging with JSON Format

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'json': {
            'format': '{"timestamp": "%(asctime)s", "level": "%(levelname)s", "logger": "%(name)s", "message": "%(message)s", "module": "%(module)s", "function": "%(funcName)s", "line": %(lineno)d}',
            'datefmt': '%Y-%m-%d %H:%M:%S',
        },
        'verbose': {
            'format': '[{levelname}] {asctime} {name} {message}',
            'style': '{',
            'datefmt': '%Y-%m-%d %H:%M:%S',
        },
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose' if DEBUG else 'json',
            'filters': [] if DEBUG else ['require_debug_false'],
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR.parent / 'logs' / 'django.log',
            'maxBytes': 1024*1024*15,  # 15MB
            'backupCount': 10,
            'formatter': 'json',
        },
        'security_file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR.parent / 'logs' / 'security.log',
            'maxBytes': 1024*1024*15,  # 15MB
            'backupCount': 10,
            'formatter': 'json',
            'filters': ['require_debug_false'],
        },
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['require_debug_false'],
            'formatter': 'verbose',
            'include_html': True,
        },
    },
    'root': {
        'handlers': ['console', 'file'],
        'level': env.str('LOG_LEVEL', default='INFO'),
    },
    'loggers': {
        'django': {
            'handlers': ['console', 'file'],
            'level': 'INFO',
            'propagate': False,
        },
        'django.security': {
            'handlers': ['security_file', 'mail_admins'],
            'level': 'WARNING',
            'propagate': False,
        },
        'django.db.backends': {
            'handlers': ['console'] if DEBUG else [],
            'level': 'DEBUG' if DEBUG else 'WARNING',
            'propagate': False,
        },
        'barodybroject': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG' if DEBUG else 'INFO',
            'propagate': False,
        },
        'parodynews': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG' if DEBUG else 'INFO',
            'propagate': False,
        },
    },
}

Log Directory Management

# Ensure logs directory exists
logs_dir = BASE_DIR.parent / 'logs'
logs_dir.mkdir(exist_ok=True)

Performance Optimization

Static Files Optimization

Production Static File Configuration

if IS_PRODUCTION:
    # Use manifest static files storage for production
    STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

    # Optimize static file serving
    STATIC_URL = env.str('STATIC_URL', default='/static/')
    STATIC_ROOT = env.str('STATIC_ROOT', default=str(BASE_DIR / 'staticfiles'))

    # Media files configuration
    MEDIA_URL = env.str('MEDIA_URL', default='/media/')
    MEDIA_ROOT = env.str('MEDIA_ROOT', default=str(BASE_DIR / 'media'))

    # Static file compression
    STATICFILES_FINDERS = [
        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    ]
else:
    # Development static file serving
    STATIC_URL = '/static/'
    STATIC_ROOT = BASE_DIR / 'staticfiles'
    MEDIA_URL = '/media/'
    MEDIA_ROOT = BASE_DIR / 'media'

Session Optimization

Optimized Session Configuration

# Session configuration
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'  # Hybrid session storage
SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 3600 if IS_PRODUCTION else 86400  # 1 hour prod, 24 hours dev
SESSION_SAVE_EVERY_REQUEST = False  # Only save when modified
SESSION_EXPIRE_AT_BROWSER_CLOSE = IS_PRODUCTION

Deployment Configuration

Container and Cloud Configuration

Azure Container Apps Configuration

# Container-specific settings
CONTAINER_APP_NAME = env.str('CONTAINER_APP_NAME', default='barodybroject')

# Allowed hosts configuration
if IS_PRODUCTION:
    ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[
        f'{CONTAINER_APP_NAME}.azurecontainerapps.io',
        'barodybroject.com',
        'www.barodybroject.com',
    ])

    # CSRF trusted origins
    CSRF_TRUSTED_ORIGINS = [
        f'https://{CONTAINER_APP_NAME}.azurecontainerapps.io',
        'https://barodybroject.com',
        'https://www.barodybroject.com',
    ]
else:
    ALLOWED_HOSTS = ['*']  # Allow all hosts in development
    CSRF_TRUSTED_ORIGINS = [
        'http://localhost:8000',
        'http://127.0.0.1:8000',
        'http://localhost:8001',
        'http://127.0.0.1:8001',
    ]

Health Checks and Monitoring

Application Health Monitoring

# Health check configuration
HEALTH_CHECK = {
    'DISK_USAGE_MAX': 90,  # Percentage
    'MEMORY_USAGE_MAX': 90,  # Percentage
}

# Performance monitoring
if IS_PRODUCTION:
    # Add performance monitoring middleware
    MIDDLEWARE.insert(0, 'django.middleware.common.BrokenLinkEmailsMiddleware')

Testing & Validation

Configuration Testing

Django System Checks

# Development environment testing
python manage.py check

# Production deployment checks
python manage.py check --deploy

# Database connectivity testing
python manage.py migrate --run-syncdb

Environment Validation

# Test environment variable loading
python -c "
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'barodybroject.settings')
from django.conf import settings
print('Environment:', 'Production' if settings.IS_PRODUCTION else 'Development')
print('Debug:', settings.DEBUG)
print('Database:', settings.DATABASES['default']['ENGINE'])
print('Cache:', settings.CACHES['default']['BACKEND'])
"

Performance Testing

Load Testing Configuration

# Load testing settings
if env.bool('LOAD_TESTING', default=False):
    # Disable unnecessary middleware for load testing
    MIDDLEWARE = [m for m in MIDDLEWARE if 'debug' not in m.lower()]

    # Optimize for load testing
    LOGGING['handlers']['console']['level'] = 'ERROR'
    LOGGING['root']['level'] = 'ERROR'

Migration Guide

Migrating from Previous Configuration

1. Environment Variable Migration

# Update .env file with new variables
cp .env .env.backup
# Add new environment variables from template

# Test new configuration
python manage.py check

2. Database Migration

# Backup existing database
python manage.py dumpdata > backup.json

# Apply new database settings
python manage.py migrate

# Test database connectivity
python manage.py shell -c "from django.db import connection; connection.ensure_connection(); print('Database connected successfully')"

3. Cache Setup

# Create cache table for database cache fallback
python manage.py createcachetable

# Test Redis connection (if using Redis)
python manage.py shell -c "from django.core.cache import cache; cache.set('test', 'value'); print('Cache test:', cache.get('test'))"

4. Static Files Migration

# Collect static files with new configuration
python manage.py collectstatic --noinput

# Test static file serving
python manage.py runserver

Rollback Procedures

Emergency Rollback

# Restore previous environment
cp .env.backup .env

# Restart application
# For Docker: docker-compose restart
# For systemd: systemctl restart your-app

Troubleshooting

Common Issues and Solutions

1. Environment Variable Issues

# Issue: RUNNING_IN_PRODUCTION not being read correctly
# Solution: Check environment variable precedence
env | grep RUNNING_IN_PRODUCTION
unset RUNNING_IN_PRODUCTION  # If set in shell environment

2. Database Connection Issues

# Issue: Database connection failures
# Solution: Verify database settings and connectivity
python manage.py dbshell  # Test database connection

3. Cache Configuration Issues

# Issue: Redis connection failures
# Solution: Use database cache fallback
export REDIS_URL=""  # Force fallback to database cache
python manage.py check

4. Static Files Issues

# Issue: Static files not loading
# Solution: Verify static file configuration
python manage.py collectstatic --dry-run
python manage.py findstatic admin/css/base.css

Debug Mode Configuration

Enable Comprehensive Debugging

# Set environment for debugging
export DEBUG=True
export LOG_LEVEL=DEBUG
export ENABLE_DEBUG_TOOLBAR=True

# Run with verbose output
python manage.py runserver --verbosity=2

Performance Debugging

Database Query Analysis

# Add to development settings for query debugging
if DEBUG:
    LOGGING['loggers']['django.db.backends']['level'] = 'DEBUG'

    # Show queries in debug toolbar
    DEBUG_TOOLBAR_CONFIG = {
        'SHOW_TOOLBAR_CALLBACK': lambda request: True,
        'HIDE_DJANGO_SQL': False,
    }

Cache Performance Analysis

# Monitor cache hit rates
if DEBUG:
    CACHES['default']['OPTIONS'] = {
        'MONITOR_CACHE_HITS': True,
        'LOG_CACHE_OPERATIONS': True,
    }

Resources


Last Updated: October 27, 2025
Maintainer: Barodybroject Team
Version: 2.0.0
Status: Production Ready

This comprehensive guide ensures enterprise-grade Django configuration for the Barodybroject application, providing security, performance, and maintainability for production deployment while maintaining excellent developer experience.