# ThrillWiki Configuration System This document provides an overview of the ThrillWiki configuration system, including how settings are organized, how to configure different environments, and best practices for managing configuration. ## Architecture Overview ThrillWiki uses a modular configuration architecture that separates concerns and makes settings easy to manage across different environments. ### Directory Structure ``` backend/config/ ├── django/ # Environment-specific settings │ ├── base.py # Core Django settings (imports from settings/) │ ├── local.py # Local development settings │ ├── production.py # Production settings │ └── test.py # Test settings ├── settings/ # Modular settings modules │ ├── __init__.py # Package documentation │ ├── cache.py # Redis caching configuration │ ├── database.py # Database and GeoDjango settings │ ├── email.py # Email backend configuration │ ├── logging.py # Logging formatters, handlers, loggers │ ├── rest_framework.py # DRF, JWT, CORS, API docs │ ├── secrets.py # Secret management utilities │ ├── security.py # Security headers and authentication │ ├── storage.py # Static/media files and WhiteNoise │ ├── third_party.py # Allauth, Celery, Cloudflare, etc. │ └── validation.py # Environment variable validation └── celery.py # Celery task queue configuration ``` ### How Settings Are Loaded 1. **base.py** defines core Django settings and imports all modular settings 2. Environment-specific files (**local.py**, **production.py**, **test.py**) extend base.py 3. The active settings module is determined by `DJANGO_SETTINGS_MODULE` 4. Modular settings use **python-decouple** to read environment variables ### Environment Selection The settings module is selected in this order: 1. `DJANGO_SETTINGS_MODULE` environment variable (explicit override) 2. Test command detection (`manage.py test` → `config.django.test`) 3. Production indicators (cloud provider environment variables) 4. `DEBUG=False` → `config.django.production` 5. Default → `config.django.local` ## Configuration Methods ### Using Environment Variables Environment variables are the primary configuration method. Create a `.env` file from the template: ```bash cp .env.example .env # Edit .env with your values ``` ### python-decouple All settings modules use python-decouple for consistent environment variable handling: ```python from decouple import config # String with default DEBUG = config("DEBUG", default=True, cast=bool) # Integer with validation PORT = config("PORT", default=8000, cast=int) # List from comma-separated string ALLOWED_HOSTS = config( "ALLOWED_HOSTS", default="localhost", cast=lambda v: [s.strip() for s in v.split(",")] ) ``` ## Environment-Specific Configuration ### Local Development (`config.django.local`) - Debug mode enabled - Local memory cache (no Redis required) - Console email backend - Development middleware (nplusone, debug toolbar) - Relaxed security settings ### Production (`config.django.production`) - Debug mode disabled - Redis caching required - Strict security settings (HSTS, secure cookies) - JSON logging for log aggregation - Sentry integration (optional) ### Test (`config.django.test`) - In-memory SpatiaLite database - In-memory cache - Fast password hashing - Logging disabled - Celery tasks run synchronously ## Modular Settings Reference ### database.py - `DATABASES` - Database connection configuration - `GDAL_LIBRARY_PATH`, `GEOS_LIBRARY_PATH` - GeoDjango libraries - `CONN_MAX_AGE` - Connection pooling - `DATABASE_OPTIONS` - PostgreSQL-specific settings ### cache.py - `CACHES` - Redis cache backends (default, sessions, api) - `SESSION_*` - Session storage settings - `CACHE_MIDDLEWARE_*` - Cache middleware settings ### security.py - `SECURE_*` - Security header settings - `SESSION_COOKIE_*`, `CSRF_COOKIE_*` - Cookie security - `AUTH_PASSWORD_VALIDATORS` - Password validation rules - `PERMISSIONS_POLICY` - Browser feature permissions ### email.py - `EMAIL_BACKEND` - Email sending backend - `FORWARD_EMAIL_*` - ForwardEmail configuration - SMTP settings for custom email servers ### rest_framework.py - `REST_FRAMEWORK` - DRF configuration - `CORS_*` - Cross-origin settings - `SIMPLE_JWT` - JWT token settings - `REST_AUTH` - dj-rest-auth settings - `SPECTACULAR_SETTINGS` - OpenAPI documentation ### third_party.py - `ACCOUNT_*`, `SOCIALACCOUNT_*` - Allauth settings - `CLOUDFLARE_IMAGES` - Image CDN configuration - `ROADTRIP_*` - Road trip service settings - `HEALTH_CHECK` - Health check thresholds ### storage.py - `STATIC_*`, `MEDIA_*` - File serving configuration - `STORAGES` - Django 4.2+ storage backends - `WHITENOISE_*` - Static file optimization - `FILE_UPLOAD_*` - Upload security limits ### logging.py - `LOGGING` - Complete logging configuration - Formatters: verbose, json, simple - Handlers: console, file, error_file, performance - Loggers for Django, application, and third-party ## Secret Management ### Validation Use the management command to validate configuration: ```bash # Full validation python manage.py validate_settings # Strict mode (warnings become errors) python manage.py validate_settings --strict # JSON output python manage.py validate_settings --json # Secrets only python manage.py validate_settings --secrets-only ``` ### Required Secrets These secrets must be set in all environments: | Secret | Description | |--------|-------------| | `SECRET_KEY` | Django cryptographic signing key (50+ chars) | | `DATABASE_URL` | Database connection URL | ### Secret Rotation For production environments: 1. Enable rotation checking: `SECRET_ROTATION_ENABLED=True` 2. Track versions: `SECRET_KEY_VERSION=1` 3. Monitor expiry warnings in logs 4. Rotate secrets before expiry See [Secret Management Guide](./secret-management.md) for detailed procedures. ## Troubleshooting ### Common Issues **Settings module not found:** ``` ModuleNotFoundError: No module named 'config.django.local' ``` Ensure you're running commands from the `backend/` directory. **Required environment variable missing:** ``` decouple.UndefinedValueError: SECRET_KEY not found ``` Create a `.env` file or set the environment variable. **Database connection failed:** ``` django.db.utils.OperationalError: could not connect to server ``` Check `DATABASE_URL` format and database server status. ### Validation Errors Run validation to identify configuration issues: ```bash python manage.py validate_settings ``` ### Debug Configuration To debug configuration loading: ```python # In Django shell from django.conf import settings print(settings.DEBUG) print(settings.DATABASES) ``` ## Best Practices 1. **Never commit secrets** - Use `.env` files or secret management services 2. **Use environment variables** - Don't hardcode configuration values 3. **Validate on startup** - Catch configuration errors early 4. **Separate environments** - Use different settings for dev/staging/production 5. **Document custom settings** - Add comments explaining non-obvious configuration 6. **Use appropriate defaults** - Secure defaults for production, convenient for development ## Related Documentation - [Environment Variables Reference](./environment-variables.md) - [Secret Management Guide](./secret-management.md) - [Deployment Guide](./deployment.md)