.. _configuration: Configuration ============= This template follows the `12-factor app methodology`_ for configuration management. The core principle is simple: **store configuration in environment variables**, not in code. This approach enables the same codebase to run in development, staging, and production with different configurations—without modifying any code. .. _12-factor app methodology: https://12factor.net/config How django-environ Works ------------------------ The template uses `django-environ`_ to read environment variables with type conversion and defaults: .. code-block:: python import environ env = environ.Env() # String (default) EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend") # Boolean conversion DEBUG = env.bool("DJANGO_DEBUG", False) # Integer conversion CONN_MAX_AGE = env.int("CONN_MAX_AGE", default=60) # List parsing (comma-separated) ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["example.com"]) # Database URL parsing DATABASES = {"default": env.db("DATABASE_URL")} .. _django-environ: https://django-environ.readthedocs.io/ Settings File Layering ---------------------- Configuration is organized into layered settings files: ``config/settings/base.py`` Shared settings used by all environments. Reads from environment variables with sensible defaults for optional settings. ``config/settings/local.py`` Development overrides. Sets ``DEBUG=True``, uses console email backend, enables debug toolbar. ``config/settings/production.py`` Production hardening. **No defaults for secrets**—missing required variables raise errors. Enables security headers (HSTS, secure cookies, SSL redirect). ``config/settings/test.py`` Test optimizations. Uses fast password hasher, in-memory email backend. The active settings file is determined by ``DJANGO_SETTINGS_MODULE``: .. code-block:: bash # Development DJANGO_SETTINGS_MODULE=config.settings.local # Production DJANGO_SETTINGS_MODULE=config.settings.production # Testing DJANGO_SETTINGS_MODULE=config.settings.test The .env File ------------- Automatic Secret Generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~ When you generate a project, the template automatically creates a ``.env`` file with cryptographically secure random values for: - ``POSTGRES_USER`` — 32-character random string - ``POSTGRES_PASSWORD`` — 64-character random string - ``DJANGO_SECRET_KEY`` — 64-character random string - ``DJANGO_ADMIN_URL`` — Random admin path (e.g., ``a8f3b2c1d4e5/``) - ``CELERY_FLOWER_USER`` / ``CELERY_FLOWER_PASSWORD`` — If Celery is enabled This ensures every generated project has unique secrets out of the box. .env vs .env.example ~~~~~~~~~~~~~~~~~~~~ Two environment files exist: ``.env.example`` Template showing all available variables. **Committed to version control** as documentation. ``.env`` Actual configuration with real secrets. **Never committed**—automatically added to ``.gitignore``. The DJANGO_READ_DOT_ENV_FILE Setting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This controls whether Django loads the ``.env`` file: .. code-block:: python READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=False) if READ_DOT_ENV_FILE: env.read_env(str(BASE_DIR / ".env")) **Important**: OS environment variables always take precedence over ``.env`` file values. - **Docker development**: Set ``DJANGO_READ_DOT_ENV_FILE=True`` in the ``.env`` file. Docker Compose loads this via ``env_file`` directive. - **Production**: Set to ``False`` (the default). Configure environment variables through your hosting platform instead. Configuration by Environment ---------------------------- Local Development (Docker) ~~~~~~~~~~~~~~~~~~~~~~~~~~ The recommended development setup uses Docker Compose: 1. Project generation creates ``.env`` with secrets 2. ``docker-compose.local.yml`` loads ``.env`` via: .. code-block:: yaml services: django: env_file: - ./.env 3. All services (Django, PostgreSQL, Redis) share the same environment The ``.env`` file contains: .. code-block:: bash # PostgreSQL POSTGRES_HOST=postgres POSTGRES_PORT=5432 POSTGRES_DB=your_project POSTGRES_USER= POSTGRES_PASSWORD= # Django DJANGO_READ_DOT_ENV_FILE=True USE_DOCKER=yes DJANGO_SECRET_KEY= DJANGO_ADMIN_URL=/ # Redis (if Celery enabled) REDIS_URL=redis://redis:6379/0 # Frontend VITE_API_URL=http://localhost:8000 Local Development (without Docker) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If developing without Docker, you can use `direnv`_ for automatic environment loading. The template includes a ``.envrc`` file: .. code-block:: bash dotenv export DATABASE_URL=postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB .. _direnv: https://direnv.net/ Production Deployment ~~~~~~~~~~~~~~~~~~~~~ In production, configure environment variables through your hosting platform: - **Heroku**: Config Vars in the dashboard or ``heroku config:set`` - **AWS**: Parameter Store, Secrets Manager, or ECS task definitions - **Railway/Render**: Environment variable settings in dashboard **Required variables** (no defaults—deployment fails if missing): .. list-table:: :header-rows: 1 :widths: 30 70 * - Variable - Description * - ``DJANGO_SECRET_KEY`` - Long random string for cryptographic signing * - ``DATABASE_URL`` - PostgreSQL connection string * - ``DJANGO_ADMIN_URL`` - Admin path with trailing slash (e.g., ``secret-admin/``) * - ``DJANGO_ALLOWED_HOSTS`` - Comma-separated list of allowed hostnames **Security defaults in production**: - ``SECURE_SSL_REDIRECT=True`` — Redirects HTTP to HTTPS - ``SESSION_COOKIE_SECURE=True`` — Cookies only sent over HTTPS - ``CSRF_COOKIE_SECURE=True`` — CSRF token only sent over HTTPS - ``SECURE_HSTS_SECONDS=60`` — HTTP Strict Transport Security enabled Best Practices -------------- 1. **Never commit secrets** — The ``.env`` file is gitignored for a reason 2. **Use platform-native secret management** — Heroku Config Vars, AWS Secrets Manager, etc. 3. **Different secrets per environment** — Never reuse production secrets in development 4. **Rotate secrets periodically** — Especially ``DJANGO_SECRET_KEY`` and database passwords 5. **Don't rely on .env in production** — Set ``DJANGO_READ_DOT_ENV_FILE=False`` See Also -------- - :doc:`settings` — Complete environment variable reference - :doc:`/3-deployment/deployment-on-heroku` — Heroku-specific configuration