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
- Architecture & Design Principles
- Configuration Structure
- Environment Management
- Security Configuration
- Database Optimization
- Caching Strategy
- Logging & Monitoring
- Performance Optimization
- Deployment Configuration
- Testing & Validation
- Migration Guide
- Troubleshooting
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:
- Codebase: Single codebase with environment-specific configuration
- Dependencies: Explicit dependency declaration via requirements files
- Config: Configuration stored in environment variables
- Backing Services: Treat databases, caches, and queues as attached resources
- Build/Release/Run: Strict separation of build and run stages
- Processes: Execute as stateless processes
- Port Binding: Self-contained service with port binding
- Concurrency: Scale out via the process model
- Disposability: Fast startup and graceful shutdown
- Dev/Prod Parity: Keep development and production as similar as possible
- Logs: Treat logs as event streams
- 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'
Cookie Security¶
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¶
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¶
- Environment Configuration - Complete environment variable reference
- Security Configuration - Security settings and best practices
- Performance Configuration - Performance optimization guide
- Database Configuration - Database setup and optimization
- Deployment Configuration - Deployment-specific settings
Related Documentation¶
- Project README - Main project documentation
- Changelog - Project change history
- Contributing Guidelines - How to contribute to the project
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.